13
votes

I'm getting the following error while trying to subscribe in the second time to an EventEmitter after that ngOnDestroy was invoked and called unsubscribe:

    ngOnInit() {
        this.route.params.subscribe(params => {
         this.resources.eco_id= params['id']
        });
        this.http.ReloadForm.subscribe(res=>this.OnFormLoad(res));
      }

  ngOnDestroy(){
    this.http.ReloadForm.unsubscribe();
  }

core.js:1601 ERROR Error: object unsubscribed at new ObjectUnsubscribedError (ObjectUnsubscribedError.js:6) at EventEmitter.push../node_modules/rxjs/_esm5/internal/Subject.js.Subject._trySubscribe (Subject.js:86) at EventEmitter.push../node_modules/rxjs/_esm5/internal/Observable.js.Observable.subscribe (Observable.js:28) at EventEmitter.push../node_modules/@angular/core/fesm5/core.js.EventEmitter.subscribe (core.js:3743) at EcoProcedureFormComponent.push../src/app/forms/eco-form/eco-procedure-form.component.ts.EcoProcedureFormComponent.ngOnInit (eco-procedure-form.component.ts:57) at checkAndUpdateDirectiveInline (core.js:10105) at checkAndUpdateNodeInline (core.js:11371) at checkAndUpdateNode (core.js:11333) at prodCheckAndUpdateNode (core.js:11877) at Object.eval [as updateDirectives] (EcoProcedureFormComponent_Host.ngfactory.js:10)

without the unsubscribe at ngOnDestroy everything work just fine, but I must to release the subscription some how.

How can I solve it?

Thank you

1

1 Answers

19
votes

You should create a Subscription variable and assign the subscription's return value to it. Then in the ngOnDestroy method you should release the subscription by calling its unsubscribe method.

Example:

private routesSubscription: Subscription;
private serviceSubscription: Subscription;

ngOnInit() {
    this.routesSubscription = this.route.params.subscribe(params => {
     this.resources.eco_id = params['id']
    });
    this.serviceSubscription = this.http.ReloadForm.subscribe(res => this.OnFormLoad(res));
}

ngOnDestroy(){
    if(this.routesSubscription){
      this.routesSubscription.unsubscribe();
    }

    if(this.serviceSubscription){
      this.serviceSubscription.unsubscribe();
    }
}

If you want to unsubscribe from more than one subscription, you can use .add() to add "children" to the subscription. Then you can unsubscribe from all subscriptions at once together. If you need more control, just add variables for each (or even split them to groups).

-- UPDATE --

Examples with the other solution:

Example 1:

subscriptions = new Subscription();

someFunc = () => {
    this.subscriptions.add(
        something.subscribe();
    );
}

ngOnDestroy(){
    if(this.subscriptions){
        this.subscriptions.unsubscribe();
    }
}

Example 2:

subscriptionGroup: Subscription[]= [];

someFunc = () => {
    this.subscriptionGroup.push(something.subscribe())
}

someOtherFunc = () => {
    this.subscriptionGroup.push(somethingElse.subscribe())
}

ngOnDestroy(){
    this.subscriptionGroup.forEach(subscription => {
        subscription.unsubscribe()
    }
}