Search code examples
angularangular2-changedetection

How to force other angular components to refresh and update the view?


I am working on an Angular +2 app where we provide the user an 'update your profile' page. The user is permitted to update their username from, say, "JSmith to "JDoe". We have a separate menu component in the upper right that displays some basic user data---username, email, etc.

Problem: After the user updates their username I want the save method to trigger updates to the menu component as well so that the displayed info--username,etc.--gets updated as well.

Question: what is the technique to execute changes to specific components?


Solution

  • If you want to notify other components of changes to data you can use a event model. Basically you create a singleton service that is injected into your components. This service has a Subject field which can be used to broadcast changes as well as subscribe to that broadcast.

    userMenu.component.ts

    import { Component, OnInit } from '@angular/core';
    import { UserStateService } from './userState.service';
    
    export class UserMenuComponent implements OnInit {
        constructor(private readonly userStateService: UserStateService) { }
    
        ngOnInit() {
            this.userStateService.userChanged
                .asObservable()
                .subcribe(userInfo => {/* do something */});
        }
    }
    

    userInput.component.ts

    import { Component, OnInit } from '@angular/core';
    import { UserStateService } from './userState.service';
    
    export class UserInputComponent {
        userData: any;
        constructor(private readonly userStateService: UserStateService) { }
    
        onSave() {
            this.userStateService.userChanged.next(this.userData);
        }
    }
    

    userState.service.ts

    import { Injectable } from '@angular/core';
    import { Observable, Subject } from 'rxjs';
    
    @Injectable({ providedIn: 'root' })
    export class UserStateService {
        userChanged = new Subject();
    }