javascript - Angular 4: use loggedInMethod to change menu -


i'm struggling find solution problem. googled hours couldn't solve.

i need change menu item in navbar template showing login vs logout when user logs in , out.

i have 2 services, authservice let user login/logout , sessionservice provides basic functions check if session set or not.

i want every time login or logout user (so update localstorage in sessionservice) components use updated too.

i tried .subscribe, .map cannot make work. thing make work call this.loggedin.next(this._sessionservice.issetusersession()); in login , logout methods.

please, doing wrong?

navbar.component.html

<div class="dropdown-menu" aria-labelledby="dropdownaccount">  <ng-template *ngif="(loggedin$ | async); else elsediv;">    <a class="nav-link" href="javascript:void(0)" (click)="logout()">logout</a>  </ng-template>  <ng-template #elsediv>                           <a class="nav-link" href="javascript:void(0)"(click)="login(...);">       login    </a>  </ng-template> </div> 

navbar.component.ts

import {component, oninit} '@angular/core'; import {authservice} '../services/auth.service';  @component({     moduleid: module.id,     selector: 'app-nav-bar',     templateurl: 'navbar.component.html',     styleurls: ['./navbar.component.css'], })  export class navbarcomponent implements oninit {     isnavbarcollapsed = true;       loggedin$: any;      constructor(                 private authservice: authservice) {     }      ngoninit() {         this.loggedin$ = this.authservice.isloggedin;     } } 

auth.service.ts

import {injectable} '@angular/core'; import {http, response} '@angular/http'; import 'rxjs/add/operator/map'; import 'rxjs/add/observable/throw'; import 'rxjs/add/operator/catch'; import 'rxjs/add/operator/do'; import {iuser} '../entities/user'; import {sessionservice} './session.service'; import {router} '@angular/router'; import {subject} 'rxjs/subject';  @injectable() export class authservice {      private loggedin: subject<boolean> = new subject<boolean>();      isloggedin() {         return this.loggedin.asobservable();     }      constructor(private _http: http,                 private _sessionservice: sessionservice,                 private _router: router) {         this.loggedin.next(this._sessionservice.issetusersession());     }      login(user: iuser) {         return this._http.get('assets/api/responsesuccess.json?email=' + user.email + '&password=' + user.password)             .map((responselogin => {                 const jsonresponse = responselogin.json();                 if (jsonresponse.response === 'success') {                     const userresponse: iuser = jsonresponse.user;                     this._sessionservice.setusersession(userresponse);               //this.loggedin.next(this._sessionservice.issetusersession()); ==> makes works don't want fo call every time change session, want session syncs automatically                      return true;                 } else {                    console.log("error loggin in");                     return false;                 }             }));     }      logout() {         this._sessionservice.clearusersession();         // this.loggedin.next(this._sessionservice.issetusersession()); =>> same here                  return this._router.navigate(['/']);       } } 

session.service.ts

import {injectable} '@angular/core'; import {iuser} '../entities/user'; import {isnullorundefined} 'util'; import {subject} "rxjs/subject";  @injectable() export class sessionservice {      issetusersession(): boolean {         return !!localstorage.getitem('user');     }      clearusersession() {         localstorage.removeitem('user');     }      setusersession(user: iuser) {         localstorage.setitem('user', json.stringify(user));     } } 

please make following changes.

use behaviorsubject instead of subject.

a behaviorsubject holds 1 value. when subscribed emits value immediately. subject doesn't hold value. when set subject variable, doesn't reflect in nav component.

auth.service.ts

private loggedin = new behaviorsubject<boolean>(false);  isloggedin() {          return this.loggedin.asobservable();     } 

set loggedin variable in login , logout functions.

login(user: iuser) {         return this._http.get('assets/api/responsesuccess.json?email=' + user.email + '&password=' + user.password)             .map((responselogin => {                 const jsonresponse = responselogin.json();                 if (jsonresponse.response === 'success') {                     const userresponse: iuser = jsonresponse.user;                     this._sessionservice.setusersession(userresponse);                this.loggedin.next(this._sessionservice.issetusersession());                      return true;                 } else {                    console.log("error loggin in");                     return false;                 }             }));     }   logout() {         this._sessionservice.clearusersession();         this.loggedin.next(this._sessionservice.issetusersession());          return this._router.navigate(['/']);       } 

in navbar.component.ts replace loggedin$: any; by

isloggedin$: observable<boolean>;   

an explanation follows.

the behaviorsubject keeps latest value cached set when user log ins or logs out. when observer subscribes isloggedin(), cached value going emitted right away, depending on user signed in or not.

this code work sure, using in current project.


Comments

Popular posts from this blog

What is happening when Matlab is starting a "parallel pool"? -

angular - DownloadURL return null in below code -

php - Cannot override Laravel Spark authentication with own implementation -