8

When I load the page first time, on some pages it shows unsubscribe error in ngOnDestroy as I am unsubscribing subscribes in it.

I am not sure why ngOnDestroy is called at the init of the component.

enter image description here

enter image description here

This is the error what I see when the page is first loaded.

I thought this was some issue from angular2-multiselect-dropdown but in some other component, its own ngOnDestory is called as well and says subscription to unsubscribe is not defined.

So I added if condition to remove the error message. enter image description here

This is the creation of the subscription.

enter image description here enter image description here

Actually I don't think it has any other problem in defining the observable.

So is this a problem with angular component lifecycle or possibly an issue from angular2-multiselect-dropdown?

I didn't see this error before and not sure what I did wrong. Can anyone had similar issue or help me on this? Thanks in advance.

purplefeel
  • 193
  • 2
  • 16
  • Can you please show the code of creation "this.changeName$" – Abdulrahman Falyoun Apr 08 '19 at 14:01
  • can you create a working example? – Aravind Apr 08 '19 at 14:02
  • Thank you for your comments. This is a large app so its not that easy to imitate all the logic in a working example. And I guess if I make simple testing app, it would work in there. Did you have any chance to get this kinda message before? – purplefeel Apr 08 '19 at 14:07
  • Let me edit the post to show the creation of that subscription. – purplefeel Apr 08 '19 at 14:08
  • 1
    @purplefeel try recreating the issue on https://stackblitz.com. Most of the time, trying to reproduce the issue also shows you what you did wrong. And anyway, without your code, we can't tell you what's wrong, so please, post at least the code of your component. –  Apr 08 '19 at 14:11
  • 2
    I think the key part will be the template of the _parent_ of the component that unexpectedly gets ngOnDestroyed. Is the problematic child wrapped in some *ngIf, maybe? – mbojko Apr 08 '19 at 14:19
  • 1
    It is unlikely that the destroy function is being called by the lifecycle before the init function. Can you place a breakpoint inside `ngOnDestroy` and look at the stack trace to see what is actually triggering this code? – Vlad274 Apr 08 '19 at 14:25
  • @purplefeel, we understand that it is huge app, but try to recreate this scenario in the [**stackblitz**](https://stackblitz.com/) so we can easily help you – Aravind Apr 08 '19 at 14:26
  • I installed Angular2-multiselect-dropdown and it is not wrapped in ngIF. – purplefeel Apr 08 '19 at 14:27
  • Let me place a breakpoint and check. Whilst, the problem is, I can stop showing the message for my components in any ways, like adding if condition, not sure this is bad solution, but for the child component : angular2-multiselect-dropdown, I can't do anything on it to handle it's subscription as it's npm installed in node-modules. – purplefeel Apr 08 '19 at 14:34

4 Answers4

10

I had a similar issue with components that i have used with routes. If i added logging to the constructor, ngOnInit and ngOnDestroy the output looked like the following:

  • constructor
  • ngOnDestroy
  • constructor
  • ngOnInit

In my case the problem was how i used <router-outlet>. Simplyfied my template looked like this:

<div *ngIf="hasLayout()">
    <app-navigation></app-navigation>
    <ng-container *ngTemplateOutlet="routerOutlet"></ng-container>
</div>

<div *ngIf="!hasLayout()">
    <ng-container *ngTemplateOutlet="routerOutlet"></ng-container>
</div>

<ng-template #routerOutlet>
    <router-outlet></router-outlet>
</ng-template>

(inspired by: https://stackoverflow.com/a/51725607/7662651)

I changed it so that i have only one <router-outlet> component without <ng-template> in my template. Similar to this:

<div *ngIf="hasLayout()">
    <app-navigation></app-navigation>
</div>

<router-outlet></router-outlet>

The reason for this behavior is a unlucky combination of a change of the value that controlls which <router-outlet> is used and a async auth guard. In my case the auth guard is waiting that the login is initialized and the initialized login switches the <router-outlet>.

Here is an example that reproduces the unwanted behavior: https://stackblitz.com/edit/angular-27vrnz

Markus Hettich
  • 544
  • 6
  • 12
0

What is your version of rxjs?

If rx is v5, ok you can use .unsubscribe() on a subscriber but if is it v4 you have to use .dispose().

This seems to be the only problem.

0

Do you redirect to different page in your constructor?

Based on these two pages it's the only possibility when onDestroy is called without onInit(). Angular 4 - Can OnDestroy be run without the OnInit ever being triggered?

https://www.bennadel.com/blog/3356-ngoninit-may-not-get-called-before-ngondestroy-is-called-in-angular-4-4-6.htm

none_
  • 535
  • 4
  • 9
  • Thank you for the references. I don't have any redirection in the constructor. And I found that when I reload the page with F5 or recompile, it shows that ngOndestroy error, but if I first reload on other page and navigate to it, it doesn't show that error. Also, it shows error after init, in short, ngOnDestory is called after init, while the angular2-multiselect-dropdown unsubscribe error is showing before init as shown in the screenshot. – purplefeel Apr 08 '19 at 16:23
  • I am doing lazy loading modules and it can be related with it? I am getting this so was figuring it out as well. --- WARNING in Duplicated path in loadChildren detected during a rebuild. We will take the latest version detected and override it to save rebuild time. You should perform a full build to validate that your routes don't overlap. --- – purplefeel Apr 08 '19 at 16:29
0

Had this issue before, delete you .angular file and reload ng serve

Sean
  • 1
  • You might want to give more details on why this procedure could help and on the potential risks of deleting the file (will data be lost?) – mozway Aug 04 '23 at 12:16
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Aug 08 '23 at 13:35