Sunil Kumar
Sunil Kumar

Reputation: 949

Angular : View not updating when variable changed asynchronously

Here I am subscribing notification$ of Notification service in App.Component.ts. Every thing is going good, I have changed value in ngOnInit of App.Component.ts but its view not rendering/updating accordingly.

But when go on another view I found view has changed accordingly(but not at the same time its value changed).

App.Component.ts :

export class AppComponent implements OnInit {
      notification: string;
      public showNotification: boolean = true;
     constructor(private notificationService: NotificationService) {}
    ngOnInit() {  
        this.notificationService
          .notification$
          .subscribe(message => {
            debugger;      // message is here 
            this.showNotification = true;
              this.notification = message;       
          });
      }
    }

Notification Service :

import { Injectable } from '@angular/core';    
import { Observable } from 'rxjs/Observable';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';    
import 'rxjs/add/operator/publish';
import { Subject } from 'rxjs/Subject';    

@Injectable()
export class NotificationService {
  private _notification: BehaviorSubject<string> = new BehaviorSubject(null);
  readonly notification$: Observable<string> = this._notification.asObservable().publish().refCount();    
  constructor() { }    
  notify(message) {        
    this._notification.next(message);
    //setTimeout(() => this._notification.next(null), 3000);
  }    
}

Error Service :

import { ErrorHandler, Injectable, Injector } from '@angular/core';
import { HttpErrorResponse } from '@angular/common/http';
import { Router } from '@angular/router';    
import * as StackTraceParser from 'error-stack-parser';   
import { NotificationService } from '../_common/notification.service';    

@Injectable()
export class ErrorsService implements ErrorHandler {
  constructor(
    private injector: Injector
  ) { }

  handleError(error: Error | HttpErrorResponse) {       
    const notificationService = this.injector.get(NotificationService);        
    if (error instanceof HttpErrorResponse) {     
      return notificationService.notify(`${error.status} - ${error.message}`);
    }
}

Upvotes: 3

Views: 1134

Answers (1)

cezn
cezn

Reputation: 3035

If changes were reflected later it must be change detection issue. Http response callbacks normally are followed by change detection run, but if you have ChangeDetectionStrategy.OnPush your component will not be marked for check. You can do this explicitly. Just inject ChangeDetectorRef instance and call its markForCheck() method when necessary:

    constructor(private notificationService: NotificationService, private cd: ChangeDetectorRef) {}

    ngOnInit() {  
        this.notificationService
          .notification$
          .subscribe(message => {
            debugger;      // message is here 
            this.showNotification = true;
            this.notification = message;
            this.cd.markForCheck();
            // if markForCheck didn't help, try to trigger change detection mannually:
            // this.cd.detectChanges(); 
          });
      }

Upvotes: 2

Related Questions