Reputation: 588
I'm using Angular 9, where I want to dynamically change data of a menu item when a person logs in. But instead, since the menu gets loaded along with the home page, when a person logs in, the data change is not reflected in the menu items until I refresh the page manually. I tried using Renderer 2, ChangeDetectorRef and ElementRef but failded to reload the menu automatically. Below I'm adding just the relevant elements since the actual component code is long. Ask me if you need to know anything else:
Html:
<div class="widget-text">
<a mat-button [matMenuTriggerFor]="accountMenu" #accountMenuTrigger="matMenuTrigger" *ngIf="!isLoggedIn">
<mat-icon>person</mat-icon>
<span fxShow="false" fxShow.gt-sm class="flag-menu-title">Account</span>
<mat-icon class="mat-icon-sm caret cur-icon">arrow_drop_down</mat-icon>
</a>
<mat-menu #accountMenu="matMenu" [overlapTrigger]="false" xPosition="before" class="app-dropdown">
<span>
<button mat-menu-item [routerLink]="['/admin/login']" routerLinkActive="router-link-active">
<mat-icon >person</mat-icon>
<span>Login</span>
</button>
<button mat-menu-item [routerLink]="['/admin/login']" routerLinkActive="router-link-active">
<mat-icon>person_add</mat-icon>
<span>Register</span>
</button>
</span>
</mat-menu>
<a mat-button [matMenuTriggerFor]="profileMenu" #profileMenuTrigger="matMenuTrigger" *ngIf="isLoggedIn">
<mat-icon>person</mat-icon>
<span fxShow="false" fxShow.gt-sm class="flag-menu-title">Howdy, {{name}}</span>
<mat-icon class="mat-icon-sm caret cur-icon">arrow_drop_down</mat-icon>
</a>
<mat-menu #profileMenu="matMenu" [overlapTrigger]="false" xPosition="before" class="app-dropdown">
<span>
<button mat-menu-item [routerLink]="['/admin/profile']" routerLinkActive="router-link-active">
<mat-icon >person</mat-icon>
<span>Profile</span>
</button>
<button mat-menu-item (click)="logout()">
<mat-icon>warning</mat-icon>
<span>Logout</span>
</button>
</span>
</mat-menu>
</div>
typescript:
public name;
public isLoggedIn = false;
constructor(public router: Router, private cartService: CartService, public sidenavMenuService:SidebarMenuService) {
this.checkLogin();
this.name = Cookie.get('userName');
}
public checkLogin(): any {
if(Cookie.get('authtoken')) {
this.isLoggedIn = true;
}
}
Upvotes: 0
Views: 2000
Reputation: 2142
You don't need to make things complicated, when you logged in your logged in guard (i.e. auth guard).
import { Injectable } from '@angular/core';
import { Router, CanActivate } from '@angular/router';
import { AuthService } from './auth.service';
@Injectable()
export class AuthGuardService implements CanActivate {
constructor(public auth: AuthService, public router: Router , private sideMenuService: SideMenuService) {}
canActivate(): boolean {
if (!this.auth.isAuthenticated()) {
this.sideMenuService.sideMenuData.next({...data}); // so here you can dispatch the side menu service data .
this.router.navigate(['dashboard']); // here after authentication it
will redirect to your dashboard
page
return false;
}
return true;
}
}
}
so after redirect when you land on the Dashboard Page , in the Dashboard component you have also inject the sideMenu Service and subscribe the BehaviourSubject menu data field .
public name;
public isLoggedIn = false; // here you don't need to check login
// because you come here from auth guard
constructor(public router: Router, private cartService: CartService,
public sidenavMenuService: SidebarMenuService) {
this.checkLogin(); // same no need to check login in each
component if you use auth guard
this.name = Cookie.get('userName');
}
public ngOnInit(){
this.sideMenuService.sideMenuData.subscribe((data)=>{
// hered you get the data dynamic , you can assign to any
// component field.
});
}
public checkLogin(): any {
if(Cookie.get('authtoken')) {
this.isLoggedIn = true;
}
}
so that's how whenever you login every time you dispatch some dynamic data and your behaviourSubject will get updated and where ever you subscribe like in Dashboard component you will get the dynamic data.
Hope it will help.
Upvotes: 1
Reputation: 23818
The constructor is executed only one time during the creation of the page.
constructor(public router: Router, private cartService: CartService, public sidenavMenuService:SidebarMenuService) {
this.checkLogin();
this.name = Cookie.get('userName');
}
Now, according to the code, if the cookie authtoken
is not found during the construction, there is no way your app to know if that was created by another (login) process.
You should call the checkLogin
function and the name
assignment right after your login cocmpletes.
Upvotes: 0