[javascript] How to Update a Component without refreshing full page - Angular

My Page structure is:

<app-header></app-header>
<router-outlet></router-outlet>
<app-footer></app-footer>

How can I update/refresh the app-header component, without refreshing the whole page?

I want to hide a "Sign-In" link in the header, once the user had successfully logged in. The header is common in all the components/routes.

This question is related to javascript angular refresh angular-components

The answer is


You can use a BehaviorSubject for communicating between different components throughout the app. You can define a data sharing service containing the BehaviorSubject to which you can subscribe and emit changes.

Define a data sharing service

import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';

@Injectable()
export class DataSharingService {
    public isUserLoggedIn: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
}

Add the DataSharingService in your AppModule providers entry.

Next, import the DataSharingService in your <app-header> and in the component where you perform the sign-in operation. In <app-header> subscribe to the changes to isUserLoggedIn subject:

import { DataSharingService } from './data-sharing.service';

export class AppHeaderComponent { 
    // Define a variable to use for showing/hiding the Login button
    isUserLoggedIn: boolean;

    constructor(private dataSharingService: DataSharingService) {

        // Subscribe here, this will automatically update 
        // "isUserLoggedIn" whenever a change to the subject is made.
        this.dataSharingService.isUserLoggedIn.subscribe( value => {
            this.isUserLoggedIn = value;
        });
    }
}

In your <app-header> html template, you need to add the *ngIf condition e.g.:

<button *ngIf="!isUserLoggedIn">Login</button> 
<button *ngIf="isUserLoggedIn">Sign Out</button>

Finally, you just need to emit the event once the user has logged in e.g:

someMethodThatPerformsUserLogin() {
    // Some code 
    // .....
    // After the user has logged in, emit the behavior subject changes.
    this.dataSharingService.isUserLoggedIn.next(true);
}

To update component

 @Injectable()
    export class LoginService{
    private isUserLoggedIn: boolean = false;

    public setLoggedInUser(flag) { // you need set header flag true false from other components on basis of your requirements, header component will be visible as per this flag then
    this.isUserLoggedIn= flag;
    }


public getUserLoggedIn(): boolean {
return this.isUserLoggedIn;
}

Login Component ts
            Login Component{
             constructor(public service: LoginService){}

public login(){
service.setLoggedInUser(true);
}
            }
Inside Header component

 Header Component ts
        HeaderComponent {
         constructor(public service: LoginService){}

         public getUserLoggedIn(): boolean { return this.service.getUserLoggedIn()}
        }

template of header component: Check for user sign in here

<button *ngIf="getUserLoggedIn()">Sign Out</button>
<button *ngIf="!getUserLoggedIn()">Sign In</button>

You can use many approach like show hide using ngIf

App Component ts
AppComponent {
 public showHeader: boolean = true;
}
App Component html
<div *ngIf='showHeader'> // you show hide on basis of this ngIf and header component always get visible with it's lifecycle hook ngOnInit() called all the time when it get visible
<app-header></app-header>
</div>
<router-outlet></router-outlet>
<app-footer></app-footer>

You can also use service

@Injectable()
export class AppService {
private showHeader: boolean = false;

public setHeader(flag) { // you need set header flag true false from other components on basis of your requirements, header component will be visible as per this flag then
this.showHeader = flag;
}

public getHeader(): boolean {
return this.showHeader;
}
}

App Component.ts
    AppComponent {
     constructor(public service: AppService){}
    }

App Component.html
    <div *ngIf='service.showHeader'> // you show hide on basis of this ngIf and header component always get visible with it's lifecycle hook ngOnInit() called all the time when it get visible
    <app-header></app-header>
    </div>
    <router-outlet></router-outlet>
    <app-footer></app-footer>

Angular will automatically update a component when it detects a variable change .

So all you have to do for it to "refresh" is ensure that the header has a reference to the new data. This could be via a subscription within header.component.ts or via an @Input variable...


an example...

main.html

<app-header [header-data]="headerData"></app-header>

main.component.ts

public headerData:int = 0;

ngOnInit(){
    setInterval(()=>{this.headerData++;}, 250);
}

header.html

<p>{{data}}</p>

header.ts

@Input('header-data') data;

In the above example, the header will recieve the new data every 250ms and thus update the component.


For more information about Angular's lifecycle hooks, see: https://angular.io/guide/lifecycle-hooks


To refresh the component at regular intervals I found this the best method. In the ngOnInit method setTimeOut function

ngOnInit(): void {
  setTimeout(() => { this.ngOnInit() }, 1000 * 10)
}
//10 is the number of seconds

One of many solutions is to create an @Injectable() class which holds data that you want to show in the header. Other components can also access this class and alter this data, effectively changing the header.

Another option is to set up @Input() variables and @Output() EventEmitters which you can use to alter the header data.

Edit Examples as you requested:

@Injectable()
export class HeaderService {
    private _data;
    set data(value) {
        this._data = value;
    }
    get data() {
        return this._data;
    }
}

in other component:

constructor(private headerService: HeaderService) {}

// Somewhere
this.headerService.data = 'abc';

in header component:

let headerData;

constructor(private headerService: HeaderService) {
    this.headerData = this.headerService.data;
}

I haven't actually tried this. If the get/set doesn't work you can change it to use a Subject();

// Simple Subject() example:
let subject = new Subject();
this.subject.subscribe(response => {
  console.log(response); // Logs 'hello'
});
this.subject.next('hello');

Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to angular

error NG6002: Appears in the NgModule.imports of AppModule, but could not be resolved to an NgModule class error TS1086: An accessor cannot be declared in an ambient context in Angular 9 TS1086: An accessor cannot be declared in ambient context @angular/material/index.d.ts' is not a module Why powershell does not run Angular commands? error: This is probably not a problem with npm. There is likely additional logging output above Angular @ViewChild() error: Expected 2 arguments, but got 1 Schema validation failed with the following errors: Data path ".builders['app-shell']" should have required property 'class' Access blocked by CORS policy: Response to preflight request doesn't pass access control check origin 'http://localhost:4200' has been blocked by CORS policy in Angular7

Examples related to refresh

How to Refresh a Component in Angular Angular + Material - How to refresh a data source (mat-table) How to Update a Component without refreshing full page - Angular How to reload page the page with pagination in Angular 2? Swift: Reload a View Controller Button that refreshes the page on click Update data on a page without refreshing How to refresh or show immediately in datagridview after inserting? Gradle project refresh failed after Android Studio update Refresh Part of Page (div)

Examples related to angular-components

How to rename a component in Angular CLI? How to Update a Component without refreshing full page - Angular Angular 2 'component' is not a known element How to get element's width/height within directives and component? Call child component method from parent class - Angular How to style child components from parent component's CSS file? What is the equivalent of ngShow and ngHide in Angular 2+? Angular 2: How to style host element of the component? How can I select an element in a component template?