Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular.io / Angular 4. How do I refresh one component view when triggering another

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

I have a NavbarComponent that renders the username.

When accessing the app the first time I am not logged in and my app redirects to the LoginComponent. My NavBar is also rendered but without a username. After successful login I am redirected to my HomeComponent.

And here is the problem. My NavBar does not show the username. But if I do a refresh/ctrl+r the username is rendered.

What is 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);
                });
    }
}
like image 952
ChrisWorks Avatar asked May 03 '17 14:05

ChrisWorks


People also ask

How do you refresh a component from another component in angular 12?

Clicking on the Reload Page button,will execute the constructor() and ngOnInit() of the AppComponent,ChildComponent and TestComponent again. 3. Clicking on the Reload Test Component button, we will navigate to the /test route and execute the constructor() and ngOnInit() of the TestComponent again.

How can I refresh a page in angular?

How to refresh component from same component in Angular? Use the this. ngOnInit(); to reload the same component instead reloading the entire page!!


1 Answers

As mentioned by JusMalcolm, OnInit doesn't run again.

But you could use a Subject to tell the NavbarComponent to fetch the 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 in your constructor:

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

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

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

Also you can use a shared Service to tell NavbarComponent to re-execute the retrieval of the user. More about shared service from the Official Docs.

like image 56
AT82 Avatar answered Oct 21 '22 22:10

AT82