Angular.io/Angular 4. How to update the view of one component when starting another

I have a simple Angular.io application. (angular-cli / 4.1.0)

I have a NavbarComponent that displays a username.

When I access the application for the first time, when I am not registered, and my application is redirected to LoginComponent. My NavBar is also displayed, but without a username. After successfully logging in, I am redirected to my HomeComponent.

And here is the problem. My NavBar does not show username. But if I do an update / ctrl + r, the username will be shown.

What's wrong?

app.component.html

<nav-bar></nav-bar> <router-outlet></router-outlet> 

navbar.compoment.ts

 import { Component, OnInit } from '@angular/core'; @Component({ selector: 'nav-bar', templateUrl: './navbar.component.html', styleUrls: ['./navbar.component.css'] }) export class NavbarComponent implements OnInit { me; ngOnInit() { this.me = JSON.parse(localStorage.getItem('currentUser')); } } 

login.component.ts

 import { Component, OnInit } from '@angular/core'; import { Router, ActivatedRoute } from '@angular/router'; import { AlertService, AuthenticationService } from '../_services/index'; @Component({ moduleId: module.id, templateUrl: 'login.component.html' }) export class LoginComponent implements OnInit { model: any = {}; loading = false; returnUrl: string; constructor( private route: ActivatedRoute, private router: Router, private authenticationService: AuthenticationService, private alertService: AlertService) { } ngOnInit() { // reset login status this.authenticationService.logout(); // get return url from route parameters or default to '/' this.returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/'; } login() { this.loading = true; this.authenticationService.login(this.model.email, this.model.password) .subscribe( data => { this.router.navigate([this.returnUrl]); }, error => { this.alertService.error(error); this.loading = false; this.errorMsg = 'Bad username or password';console.error('An error occurred', error); }); } } 
+5
source share
3 answers

As mentioned by JusMalcolm, OnInit does not start again.

But you can use Subject to tell NavbarComponent to retrieve data from local storage.

In your NavbarComponent import Subject and declare it:

 import { Subject } from 'rxjs/Subject'; .... public static updateUserStatus: Subject<boolean> = new Subject(); 

Then subscribe to your constructor:

 constructor(...) { NavbarComponent.updateUserStatus.subscribe(res => { this.me = JSON.parse(localStorage.getItem('currentUser')); }) } 

And in your LoginComponent import the NavbarComponent , and when you are successfully logged in, just call next() on the theme and the NavbarComponent will subscribe to it.

 .subscribe( data => { NavbarComponent.updateUserStatus.next(true); // here! this.router.navigate([this.returnUrl]); }, // more code here 

You can also use the shared service to tell NavbarComponent re-search the user. Read more about shared service from white papers .

+6
source

Since the component is already initialized, ngOnInit () does not start after logging in. One solution for your case is to subscribe to a router setting that checks to see if the user is logged in.

eg.

 this.route.queryParams .map(params => params['loggedIn']) .subscribe(loggedIn => { if (loggedIn) { this.me = JSON.parse(localStorage.getItem('currentUser')); } }); 
0
source

If you can return the name from the backend during authentication, you can enter the AuthenticationService in the NavbarComponent and associate the required name in navbar.component.html.

NavbarComponent:

 export class NavbarComponent { ... constructor(private authservice: AuthenticationService) {} ... } 

navbar.component.html:

 <span>Welcome {{authservice.name}}!</span> 
0
source

All Articles