Search code examples
angularangular6behaviorsubjectrxjs6

BehaviorSubject indifferent behavior


In my Angular 6 project I have 3 components, Login, Registration and Home.

enter image description here

When user successfully register in the app, I want to show this "Registration successful" message inside green area. For that I have made a BehaviorSubject inside shared.service.ts

private isRegistrationSuccessfully: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);

/* Successful registration */
  getSuccessMessage(): Observable<boolean> {
    return this.isRegistrationSuccessfully.asObservable();
  }

  setSuccessMessage(value: boolean): void {
    this.isRegistrationSuccessfully.next(value);
  }

in register.component.ts file on successful registration I am calling set method,

onSubmitRegistrationForm() {
// some code
this._sharedService.setSuccessMessage(true);
this._router.navigate(['/' + RouteConstants.LOGIN]);
}

and in the login.component.ts file I am calling getSuccessMessage() method,

successMessageSubscriber: any;

ngOnInit() {
    this.successMessageSubscriber = this._sharedService.getSuccessMessage().subscribe((flag) => {
      if (flag) {
          // code for showing div
      }
    });
  }

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

as per this code, after successful registration I am getting expected result and if I refresh the page then also getSuccessMessage() returns false, which is again expected result. But after successful registration and after login (redirecting to home component), if I logout straight away, I am still getting true value for getSuccessMessage(). Is it suppose to happened? or am I missing something here?

Edit
Also is there any other/better way, with that I can do this operations, with or without Behavior Subject?


Solution

  • Angular services are singletons (by default). Furthermore, when you call router.navigate to route to another page then some components will be destroyed but the service will not. As long as you are staying within your sites routes it wouldn’t make sense to reload the entire application every time you navigate.

    This is surprising to people sometimes because the URL changes. However, a URL change does not necessitate a page reload.

    However, when you refresh the page or when you navigate to an external page and back (like you might in an openid connect workflow) then your entire application is reloaded.

    Anyways, if you’re looking for a better approach to take then just send true and then false into your behavior subject immediately. Your component will get both values but does nothing on false. Then, when you navigate, the component will be destroyed (services are singletons but components are not) and recreated and when the new one reads it will read false.

    You could also just use a plain Subject instead of a BehaviorSubject.