Reputation: 906
In my Angular 6 project I have 3 components, Login, Registration and Home.
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?
Upvotes: 0
Views: 1168
Reputation: 272
When the login page is loaded, the subscribe method is executed. This will display the message 'registration successful', as the flag is always true.
ngOnInit() {
this.successMessageSubscriber = this._sharedService.getSuccessMessage().subscribe((flag) => {
if (flag) {
this.message="successfully registered";
}
});
}
The solution is to add another method in service to clear the flag.
clearMessage(): void {
this.isRegistrationSuccessfully.next(false);
}
Then call this method before unsubscribing.
ngOnDestroy() {
if (this.successMessageSubscriber) {
this._sharedService.clearMessage();
this.successMessageSubscriber.unsubscribe();
}
}
When the login was loaded, the message was subscribed. And when the login was unloaded, the message was unsubscribed. The flag is not cleared earlier. This change in code will reset the flag.
Upvotes: 0
Reputation: 43867
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.
Upvotes: 1