-
Notifications
You must be signed in to change notification settings - Fork 24.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Wrong 'this' in a service using Ivy #35167
Comments
How is the service being consumed? Are components extending it? I tried to reproduce it in a test like this, but it was behaving correctly. The
|
I've spent last two days trying to isolate it but I couldn't. Tried compiling smaller libraries with all the same versions but it wasn't reproducible :( This is what I have: There are 2 libraries in a workplace. One has services and a directive, second library has components that use that directive. When I compile both libraries and try to use those components in an Ivy application I get that error on destroy. I'm going to try and debug it more, so far I'm clueless... |
I got it reproduced, it happens in plain Ivy if you have two directives using the same service on the same element: https://ng-run.com/edit/Ukg0KPRiI0WMpdVaTWDc?open=app%2Fapp.component.html&aot=true Here you have a service listening to some events using that DestroyService as takeUntil and passing results to the directive. I've made two dummy directives like that, one listening to clicks and another listens to mousedowns, it doesn't really matter what they do. If you put one of them on an element it all works fine. But if you put both on the same element and that element disappears (click the button on the example) — then the error is shown. |
…times and don't call ngOnDestroy on multi provider These changes fix the following regressions in Ivy: 1. When the same provider is resolved multiple times on the same node, the first invocation had the correct context, but all subsequent ones were incorrect because we were registering the hook multiple times under different indexes in `destroyHooks`. 2. Ivy was invoking the `ngOnDestroy` hook (with an incorrect context) on `multi` providers, whereas ViewEngine did not invoke it at all. I'm somewhat conflicted about this use case, because it feels like something that should be supported, but I decided to align it with the ViewEngine behavior. The reason why I aligned it is that with the current data structure there's no way to match up the destroy hook with the object that it belongs to, because the saved data looks something like this: `[5, ngOnDestroy, 10, ngOnDestroy]` and the indexes correspond to an array. Supporting this correctly would involve a bit more design work and the current behavior is breaking user apps. Fixes angular#35167. Fixes angular#35231.
…times and don't call ngOnDestroy on multi provider These changes fix the following regressions in Ivy: 1. When the same provider is resolved multiple times on the same node, the first invocation had the correct context, but all subsequent ones were incorrect because we were registering the hook multiple times under different indexes in `destroyHooks`. 2. Ivy was invoking the `ngOnDestroy` hook (with an incorrect context) on `multi` providers, whereas ViewEngine did not invoke it at all. I'm somewhat conflicted about this use case, because it feels like something that should be supported, but I decided to align it with the ViewEngine behavior. The reason why I aligned it is that with the current data structure there's no way to match up the destroy hook with the object that it belongs to, because the saved data looks something like this: `[5, ngOnDestroy, 10, ngOnDestroy]` and the indexes correspond to an array. Supporting this correctly would involve a bit more design work and the current behavior is breaking user apps. Fixes angular#35167. Fixes angular#35231.
…times and don't call ngOnDestroy on multi provider These changes fix the following regressions in Ivy: 1. When the same provider is resolved multiple times on the same node, the first invocation had the correct context, but all subsequent ones were incorrect because we were registering the hook multiple times under different indexes in `destroyHooks`. 2. Ivy was invoking the `ngOnDestroy` hook (with an incorrect context) on `multi` providers, whereas ViewEngine did not invoke it at all. I'm somewhat conflicted about this use case, because it feels like something that should be supported, but I decided to align it with the ViewEngine behavior. The reason why I aligned it is that with the current data structure there's no way to match up the destroy hook with the object that it belongs to, because the saved data looks something like this: `[5, ngOnDestroy, 10, ngOnDestroy]` and the indexes correspond to an array. Supporting this correctly would involve a bit more design work and the current behavior is breaking user apps. Fixes angular#35167. Fixes angular#35231.
…times When the same provider is resolved multiple times on the same node, the first invocation had the correct context, but all subsequent ones were incorrect because we were registering the hook multiple times under different indexes in `destroyHooks`. Fixes angular#35167.
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
🐞 bug report
Affected Package
@angular/coreIs this a regression?
Yes, the previous version in which this bug was not present was: 8Description
I have a service abstraction over ngOnDestroy to unsubscribe from streams. Here's its source code, it's pretty simple:I have it in my library of UI components that I compile with Angular 7/8. After I tried it with Angular 9 RC application (tried with 14 and with some old ones) — when a component (from my library) using that service gets destroyed I get an error
Cannot read property 'next' of undefined
. Setting breakpoints shown me thatthis
inside this service is, for some reason, component instance that uses it, not the service instance.🔬 Minimal Reproduction
I was unable to reproduce it in an isolated environment but I have no clue how this could have happened. My code is proprietary which I'm struggling to open source but it takes a while. I was hoping maybe somebody from Angular team who knows Ivy compiler and ngcc have any ideas how this could have theoretically happened.🔥 Exception or Error
This inside ngOnDestroy of a service is component instance, not service instance
🌍 Your Environment
Angular Version:
Anything else relevant?
Sorry for such a vague description, the library is pretty straightforward Angular CLI library compiled with ng-packagr. It's just really huge and when I try to make a small library with relevant code — the issue does not reproduce. Without deep knowledge of how ngOnDestroy gets called I failed to debug it on my side.
The text was updated successfully, but these errors were encountered: