SeaBiscuit
SeaBiscuit

Reputation: 2601

RxJs Observable duplicate values

So i have pretty straight forward scenario. One subject and observable. When client logs in i publish success, when user logs out i publish false.

Problem is in subscribe method in LoginComponent First time everything works great. User logs in i get one event, but after that when user logs out second time and logs in again i get 2 same events, again if user logs out and then logs in i get 3 duplicate events and so on.

AuthService.ts

public _loggedIn: Subject<LoggedInOrResetPassword> = new Subject();
public loggedId: Observable<LoggedInOrResetPassword> = this._loggedIn.asObservable();


obtainAccessToken(){
 // ommitted
 this.httpClient.post(environment.baseUrl + url, null, requestOptions)
                .subscribe(data => {
                  this.saveToken(data);
                  this._loggedIn.next(LoggedInOrResetPassword.createTrue());
                });
  // ommitted
}


private logout(navigateTo?: string){
    this._loggedIn.next(LoggedInOrResetPassword.createFalse());
}

LoginComponent.ts

ngOnInit() {
    this.authservice.loggedId.subscribe( ( loggedInOrResetPassword: LoggedInOrResetPassword ) => {
    // HERE I GET DUPLICATE VALUES
});

Upvotes: 4

Views: 4210

Answers (1)

Picci
Picci

Reputation: 17752

The reason is that you are NOT unsubscribing when LoginComponent is destroyed.

Your code should be changed as follows

First add an instance property to LoginComponent to store the subscription, such as

export class LoginComponent implements OnInit, OnDestroy {
  .....
  loginSubscription: Subscription;
  .....
}

Then change ngOnInit so that you store the subscription in the newly added property

ngOnInit() {
    this.loginSubscription = this.authservice.loggedId.subscribe( ( loggedInOrResetPassword: LoggedInOrResetPassword ) => {
    // HERE I GET DUPLICATE VALUES
});

Eventually add ngOnDestroy to make sure you unsubscribe when the component gets destroyed

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

Take a look at the async pipe of Angular as an alternative method to subscribe to Observables and automatically unsubscribe.

Upvotes: 2

Related Questions