Shalashka
Shalashka

Reputation: 59

Angular 8 subscribe is still active even when service was destroyed

I am surely missing something here; I've got an Angular component that looks like this:

@Component({
  selector: 'lobby',
  templateUrl: './lobby.component.html',
  styleUrls: ['./lobby.component.scss'],
  providers: [LobbyService, LobbyUsersService, LobbyActivityService]
})

It has 3 services provided in the component which, according to the docs, are destroyed together with the component.

In one of the services I've got an observable subscription:

@Injectable()
export class LobbyUsersService { 
        
constructor(private _http: HttpClient, private _socketioService: SocketioService) {this._url = environment.url;
}
        
subscribe() {   
     this._socketioService.socketIoConnectObs.subscribe((connect: boolean) => {
        if (connect) {
           ....
           ....
        }
     });
}

The publisher of this event is declared in a singleton service, this way:

@Injectable({
  providedIn: 'root'
})
export class SocketioService {

    private _socketIoConnectSubject: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(null);
    public socketIoConnectObs: Observable<boolean> = this._socketIoConnectSubject.pipe(filter(val => val !== null));
    ....
    ....
    this._socket.on('connect', () => {
        this._socketIoConnectSubject.next(true);
    });
}

My question is, why does the subscribe of service LobbyUsersService getting called even after the 'lobby' component was destroyed and I'm currently routed to another component?

Upvotes: 0

Views: 55

Answers (1)

Jason White
Jason White

Reputation: 5813

You need to manage the subscription in your LobbyUsersService and unsubscribe when the service is destroyed. You can do this by having your LobbyUsersService implement OnDestroy.

import { Injectable, OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs';

@Injectable()
export class LobbyUsersService implements OnDestroy {

  private _socketIOSubscription: Subscription;
        
  constructor(
    private _http: HttpClient, 
    private _socketioService: SocketioService
  ) {
    this._url = environment.url;
  }
        
  subscribe() {   
    this._socketIOSubscription = this._socketioService.socketIoConnectObs
      .subscribe((connect: boolean) => {
        if (connect) {
          ....
          ....
        }
      });
  }

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

https://medium.com/angular-in-depth/the-best-way-to-unsubscribe-rxjs-observable-in-the-angular-applications-d8f9aa42f6a0

Upvotes: 3

Related Questions