Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Angular/RxJs – Calling next() on Observable in service after component was unsubscribe() cause ObjectUnsubscribedError

I have an Angular Service that defines a public Subject. Later under some condition, the service will call .next() on this Subject.

In addition, I have an Angular component that .subscribe() to this Subject in it’s ngOnInit() method, and call .unsubscribe() in it’s ngOnDestroy() method.

While both the service and the component are alive my code works fine. However, the user can click on a different tab in my app. Which cause my component to unload and call its ngOnDestroy() method, meaning the Observable was unsubscribed.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Starting from this point, the component no longer exists however the service is still alive – other components still use it. When the service calling .next() method after the component called .unsubscribe(), this error is thrown ObjectUnsubscribedError.
ERROR Error: Uncaught (in promise): ObjectUnsubscribedError: object unsubscribed

In addition, later if the user goes back to the tab that contains the component, the ngOnInit() is executed and the re-subscription to this observable throws the same error again.

What am I doing wrong, how can I resolve these errors?

import { Subject } from 'rxjs';

@Injectable({ providedIn: 'root' })
export class StatusService {
  public statusChange$: Subject<number>;

  public constructor(...) {
    this.statusChange$ = new Subject<number>();
  }

  public someInternalLogic(someNumber: number): void {
    this.statusChange$.next(someNumber);
    // this will throw an error if StatusComponent call .unsubscribe()
  }
}

@Component({
  selector: 'app-status',
  templateUrl: './status.component.html',
  styleUrls: ['./status.component.scss']
})
export class StatusComponent implements OnInit, OnDestroy {
  public constructor(
    private _statusService: StatusService) {}

    public ngOnInit(): void {
      this._statusService.statusChange$.subscribe(value => this._onStatusChange(value));
  }

  public ngOnDestroy(): void {
    this._statusService.statusChange$.unsubscribe();
    // after this point if the StatusService calling .next() an error will be thrown
  }

  private _onStatusChange(value: number): void {
    // ....
  }
}

>Solution :

You don’t need to unsubscribe service subject in component. Instead create an subscription variable for service subject in your component and unsubscribe it on component destroy

subscription!: Subscription;

public ngOnInit(): void {
    this.subscription = this._statusService.statusChange$.subscribe(value => this._onStatusChange(value));
}

public ngOnDestroy(): void {
    this.subscription.unsubscribe();
}

private _onStatusChange(value: number): void {
    // ....
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading