Issue
First time when web application loads, app.component is getting called and navigationbar #1 showing up. Now when user login I want to load navigationbar #2 from app.component (or let app.component UI know that user has logged in) so that ng-template can update UI and set navigationbar #2.
This is my code in app.component.html file
<div *ngIf="session === 'true'; else NoUserTemplete">
<app-app-navigation-bar-admin></app-app-navigation-bar-admin>
</div>
<ng-template #NoUserTemplete>
<app-navigation-bar></app-navigation-bar>
</ng-template>
app.component.ts file
constructor() {
this.session = localStorage.getItem('isloggedin')
}
Below method called, when user hit Login button in login.component
UserLogin()
{
this.submitted = true;
if(this.loginForm.invalid)
{
localStorage.removeItem("isloggedin");
return
}
let data = { userName: this.loginForm.value.userName, txtemail:this.loginForm.value.txtEmail}
localStorage.setItem("userinfo", JSON.stringify(data));
localStorage.setItem('isloggedin','true');
this.router.navigate(['/home']);
}
Basically what I need is, whenever localStorage's isloggedin variable is getting changed app.component should be aware about that and update the UI. How can I do that ?
Solution
You can build a service to manage the isLoggedIn variable from the local storage. This service can also expose whatever is currently saved in the local storage at the moment. The benefit of this is that you can also expose some observable, to which you can subscribe from whichever component is interested in knowing when this variable changes (including AppComponent).
@Injectable({providedIn: 'root'})
export class LoginService {
private isLoggedInSource = new ReplaySubject<boolean>(1);
public isLoggedIn$: Observable<boolean>;
constructor() {
this.isLoggedIn$ = this.isLoggedInSource.asObservable();
// sync initial value
syncLoggedIn();
}
updateLoggedInStatus(isLoggedIn: boolean) {
localStorage.setItem('isloggedin', isLoggedIn ? 'true' : 'false');
syncLoggedIn();
}
}
private syncLoggedIn(): void {
this.isLoggedInSource.next(localStorage.getItem('isloggedin') === 'true');
}
Then in your login component you can inject the LoginService to be able to update the global isLoggedIn status.
constructor(private loginService: LoginService) {}
UserLogin()
{
this.submitted = true;
if(this.loginForm.invalid)
{
this.loginService.updateLoggedInStatus(false);
return
}
let data = { userName: this.loginForm.value.userName, txtemail:this.loginForm.value.txtEmail}
localStorage.setItem("userinfo", JSON.stringify(data));
this.loginService.updateLoggedInStatus(true);
this.router.navigate(['/home']);
}
// in the logout method
// you also need to call this.loginService.updateLoggedInStatus(false);
Inside the AppComponent you can inject the same service to listen for the changes. Turn your session boolean property to an observable instead and use the async pipe:
session$: Observable<boolean>;
constructor(private loginService: LoginService) {
this.session$ = loginService.isLoggedIn$;
}
And finally, in the template of your app component you can use the session$ observable with the async pipe to decide which toolbar to show:
<div *ngIf="session$ | async; else NoUserTemplete">
<app-app-navigation-bar-admin></app-app-navigation-bar-admin>
</div>
<ng-template #NoUserTemplete>
<app-navigation-bar></app-navigation-bar>
</ng-template>
Answered By - Octavian Mărculescu
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.