I have an angular layout with the header and footer. I want to update the loading of the navigation menus based on the user's role like readonly or analyst. I saw a post here on SO and copied the BehaviorSubject
code for the header component to subscribe to a boolean change in a service. This works but I only got the one login button to change to the sign out button. In my header component ts code, I have a method that will load the menus based on the user's role. It take a list of the menu path and load only the menu items that is appropriate for the user's role. So, in addition to using *ngIf
to changing hiding base on the subscribed boolean value change, is there a way to call a method from the subscribed change when the header component is notified by the emitted change?
Any help is appreciated. Thanks.
Here is my header component ts code so far:
export const ROUTES: RouteInfo[] = [
{ path: '/Home', title: 'Home', icon: '', class: '', role: 'all'},
// admin
{ path: '/change-role', title: 'Change Role', icon: '', class: '', role: 'admin'},
{ path: '/users', title: 'User', icon: '', class: '', role: 'admin'},
{ path: '/products', title: 'products', icon: '', class: '', role: 'admin'},
{ path: '/admin', title: 'Admin', icon: '', class: '', role: 'admin'},
];
constructor(private dataSharingService: DataSharingService, private loginService: LoginService, private router : Router) {
this.dataSharingService.isUserLoggedIn.subscribe( value => { this.isUserLoggedIn = value })
}
ngOnInit() {
//this.getLoginStatus();
this.loadMenus();
}
loadMenus()
{
var role = this.loginService.getUserRole();
if (role == 'admin') {
this.menuItems = ROUTES.filter(menuItem => menuItem.role == 'admin');
}
else if (role == 'analyst' || role == 'reviewer') {
this.menuItems = ROUTES.filter(menuItem => menuItem.role == 'reviewer');
}
else if (role == ' readOnly') {
this.menuItems = ROUTES.filter(menuItem => menuItem.role == 'readOnly');
}
}
}
I guess this is what you want to do.
this.subscription = this.dataSharingService.isUserLoggedIn.subscribe(value => {
this.isUserLoggedIn = value;
this.loadMenus();
});
ngOnDestroy() {
this.subscription.unsubscribe()
}
The unsubscribe
is very important here to prevent a memory leak:
BehaviorSubject
lasts forever too because it's in the serviceBehaviorSubject
holds a subscription in the form of a callback. That callback has a reference to this
this
is the current instance of the component classIn short, if you don't unsubscribe
in the ngOnDestroy
hook, the instance of the component's class will remain forever, taking memory even if the actual component has been destroyed in the UI.