How to create a dynamic menu in angular 2?

I need to create a dynamic menu after a successful login and redirect to the home page using Angular 2. Just like in the first similar question, except that I cannot hardcode menu items.

Angular2: using routes, how to display the navigation bar after a successful login?

#app.component.html# <navbar> <!--Here I want to create menu items--> </navbar> <div class="container"> <div class="col-sm-12"> <router-outlet></router-outlet> </div> </div> <div id="footer" class="inner-wrap"> <div class="row no-padding"> <div class="col-sm-12 no-padding"> </div> </div> </div> **home.component.ts** import { Component, OnInit } from '@angular/core'; import { User } from '../_models/index'; import { UserService } from '../_services/index'; @Component({ //moduleId: module.id, templateUrl: 'home.component.html' }) export class HomeComponent implements OnInit { users: User[] = []; constructor(private userService: UserService) { } ngOnInit() { <!-- how we can create it here or any better place --> // get users from secure api end point this.userService.getUsers() .subscribe(users => { this.users = users; }); } } 

Clearly, I am new to this technology. Please, someone pick it up?

Blockquote

+7
angular angular2-template angular2-services
source share
2 answers

I managed to create a dynamic menu based on user access right after logging in. I couldn’t explain when I asked what I really want in my angular 2 application. Yesterday I searched on the angular website that we can make 2 components communicative, so I found the following links:

https://angular.io/docs/ts/latest/api/core/index/EventEmitter-class.html

Through the global emitter of events, we can do this. I share below:

GlobalEventManager:

 import { Injectable, EventEmitter } from "@angular/core"; @Injectable() export class GlobalEventsManager { public showNavBar: EventEmitter<any> = new EventEmitter(); public hideNavBar: EventEmitter<any> = new EventEmitter(); } 

The link below will help you understand how to implement the auth guard function (restrict user login without login).

http://jasonwatmore.com/post/2016/08/16/angular-2-jwt-authentication-example-tutorial

Auth.Guard.ts:

 import { Injectable } from '@angular/core'; import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'; import { GlobalEventsManager } from "../_common/gobal-events-manager"; @Injectable() export class AuthGuard implements CanActivate { constructor(private router: Router, private globalEventsManager: GlobalEventsManager) { } canActivate() { if (localStorage.getItem('currentUser')) { this.globalEventsManager.showNavBar.emit(true); return true; } else { // not logged in so redirect to login page this.router.navigate(['/login']); this.globalEventsManager.hideNavBar.emit(true); return; } } } 

The model used in menu.component.ts

Features:

 export class Features { Description: string; RoutePath: string; } 

menu.component.ts:

 import { Component, OnInit } from '@angular/core'; import { Router } from '@angular/router'; import { Features } from '../_models/features'; import { Http, Headers, RequestOptions, Response } from '@angular/http'; import { GlobalEventsManager } from "../_common/gobal-events-manager"; @Component({ selector: 'nav', templateUrl: './menu.component.html' }) export class MenuComponent { showNavBar: boolean = false; featureList: Features[] = []; private headers = new Headers({ 'Content-Type': 'application/json' }); constructor(private http: Http, private router: Router, private globalEventsManager: GlobalEventsManager) { this.globalEventsManager.showNavBar.subscribe((mode: any) => { this.showNavBar = mode; if (this.showNavBar = true) { <!-- the below function expects user id, here I have given as 1 --> this.getFeatureListByLoggedInUser(1) .then(list => { this.featureList = list; }); } }); this.globalEventsManager.hideNavBar.subscribe((mode: any) => { this.showNavBar = false; this.featureList = []; }); } private getFeatureListByLoggedInUser(userID: number): Promise<Features[]> { return this.http.get(your api url + '/Feature/GetFeatureListByUserID?userID=' + userID) .toPromise() .then(response => response.json() as Features[]) .catch(this.handleError); } private handleError(error: any): Promise<any> { console.error('An error occurred', error); // for demo purposes only return Promise.reject(error.message || error); } } 

Menu.Component.html:

 <div id="navbar" *ngIf="showNavBar" class="navbar-collapse collapse navbar-collapse-custom"> <ul class="nav navbar-nav nav_menu full-width"> <li *ngFor="let feature of featureList" class="nav_menu" routerLinkActive="active"><a class="nav-item nav-link" [routerLink]="[feature.routepath]" routerLinkActive="active">{{feature.description}}</a></li> </ul> </div> 

App.Component.ts:

  <!-- menu container --> <nav> </nav> <!-- main app container --> <div class="container-fluid body-content-custom"> <div class="col-lg-12 col-md-12 col-sm-12 col-xs-12 no-padding"> <router-outlet></router-outlet> </div> </div> <footer class="footer"> &nbsp; </footer> In the last, we need to register the providers of menu and global event manager in app.module.ts app.module.ts /// <reference path="reset-password/reset-password.component.ts" /> /// <reference path="reset-password/reset-password.component.ts" /> import './rxjs-extensions'; import { NgModule, ErrorHandler } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { HttpModule, XHRBackend } from '@angular/http'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; import { AuthGuard } from './_guards/auth.guard'; import { ContentHeaders } from './_common/headers'; import { GlobalEventsManager } from "./_common/gobal-events-manager"; import { MenuComponent } from "./menu/menu.component"; @NgModule({ imports: [ BrowserModule, FormsModule, HttpModule, AppRoutingModule, ReactiveFormsModule ], declarations: [ AppComponent, MenuComponent ], providers: [ AuthGuard, ContentHeaders, GlobalEventsManager ], bootstrap: [AppComponent] }) export class AppModule { } 

Hope this helps!

+12
source share

That's what I'm doing. Basically, the thread is tuned to the listener in the application component, which subscribes to the observed getLoggedIn. When this observable emits (the user logs in), I call the app.menu.service application to log in. When exiting the system, the opposite is true and I get noLoginMenu.

app.menu.service:

 import {RouterModule, RouterLinkActive, RouterLink} from '@angular/router'; import {Injectable} from '@angular/core'; import { Observable } from 'rxjs/Observable'; import { Subject } from 'rxjs/Subject'; import { Subscription } from 'rxjs'; @Injectable() export class AppMenuService { constructor() { } getNoLoginMenu() { return [ { label: 'Home', routerLink: [''] }, { label: 'Documents', routerLink: ['/document'] }, { label: 'Calculator', routerLink: ['/calculator'] }, { label: 'Verify', routerLink: ['/verify'] }, { label: 'About', routerLink: ['/about'] }]; } getLoggedInMenu() { return [ { label: 'Home', routerLink: [''] }, { label: 'Documents', routerLink: ['/document'] }, { label: 'Food', routerLink: ['/food'] }, { label: 'Calculator', routerLink: ['/calculator'] }, { label: 'Settings', routerLink: ['/settings'] }, { label: 'Themes', routerLink: ['/themes'] }, { label: 'About', routerLink: ['/about'] }, { label: 'Logout', routerLink: ['/logout'] //command: (event: Event) => { this.onLogout() } }]; } } 

app.component.ts

 export class AppComponent implements OnInit, OnDestroy { private items: MenuItem[]; appPageHeaderDivStyle: {}; selectedTheme: Theme; errorMessage: string; loggedIn: LoggedIn; loggedInEmail: string = ""; isLoggedIn: boolean; themeSub: Subscription; loggedInSub: Subscription; profileSub: Subscription; constructor( private as: AppMenuService, private ts: ThemeService, private ss: SettingsService, private fs: FoodService, private ls: LoginService) { } @HostListener('window:beforeunload', ['$event']) beforeUnloadHander(event) { var shutdown = this.onShutdown(); //event.preventDefault(); } ngOnInit() { this.themeSub = this.ts.getNewTheme() .subscribe( theme => this.selectedTheme = theme, error => { this.errorMessage = error }, () => this.completeGetNewTheme() ); this.ts.setTheme("Pepper-Grinder"); this.items = this.as.getNoLoginMenu(); this.ls.getLoggedIn() .subscribe( loggedIn => { if (loggedIn.error != undefined && loggedIn.error === "" && loggedIn.email != "") { this.items = this.as.getLoggedInMenu(); var us = this.ss.getUserSettings(); if (us != undefined && us.theme != null && us.theme != "") { this.ts.setTheme(us.theme); } } else { this.items = this.as.getNoLoginMenu(); this.ts.setTheme("Pepper-Grinder"); } this.completeLoggedIn(loggedIn.email); }); } ngOnDestroy() { if (this.themeSub) { this.themeSub.unsubscribe(); } if(this.loggedInSub) { this.loggedInSub.unsubscribe(); } if(this.profileSub) { this.profileSub.unsubscribe(); } } completeLoggedIn(email: string) { this.loggedInEmail = email; this.isLoggedIn = (this.loggedInEmail.length > 0); } completeGetNewTheme() { this.appPageHeaderDivStyle = this.ts.getAppPageHeaderDivStyle(); } onShutdown(): boolean { var ok = true; this.fs.completeUpdateDailyFood(); this.profileSub = this.ss.updateProfileInformation(this.ss.getUserSettings()) .subscribe( status => { console.log("logout - updated user"); }, error => { ok = false; }, ); return ok; } onLogout() { } } 

LoginService:

  loginUser(localUser: LocalUser) { this.authSub = this.auth.loginUser(localUser) .subscribe( token => { this.token = token }, error => { this.isLoggingIn = false; var errorObject = JSON.parse(error._body); this.errorMessage = errorObject.error_description; console.log(this.errorMessage); this.setLoggedIn({ email: "", password: "", error: this.errorMessage }); }, () => this.completeLogin(localUser)); } 
+3
source share

All Articles