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.