2

I have a custom error handler service which gets notified whenever there is an error in the application, now i want to notify a component about the error so that the component will show a error dialog to the user, i have tried event emitter, observer but nothing is notifying the component...

here is my service...

@Injectable()
export class ErrorHandlerService implements ErrorHandler {
  public apiError: Subject<any> = new BehaviorSubject(false);
  apiError$ = this.apiError.asObservable();
  constructor(private errorLogService: ErrorLogService
  ) {}

  handleError(error) {
    this.apiError.next(error); 
    console.log("ERROR = " + error);
  };}

And the component...

@Component({
  selector: 'app-error-log',
  templateUrl: './error-log.component.html',
  styleUrls: ['./error-log.component.scss'],
  providers: [ErrorLogService]
})
export class ErrorLogComponent implements OnInit {

  constructor(
    private errorHandlerService: ErrorHandlerService

  ) {
    this.errorHandlerService.apiError$.subscribe(data => {

      alert("error in component = " + data);

    });
  }

  onNoClick(): void {
    // this.dialogRef.close();
  }

  ngOnInit() {
    this.errorHandlerService.apiError$.subscribe(data => {

      alert("error in component = " + data);

    });
  }

}
  • Not looking at the rest of the code, but noticed this is not a global service, I guess that is what you are looking for. Therefore remove the providers array from components and only provide in module. At least that is one issue, if not the only one :) – AT82 Feb 22 '18 at 11:08
  • Tried to make the service as global(declared only in the ng-module provider), still the same issue...component is not getting triggered ... – Sunilsingh Rathore Feb 22 '18 at 11:28
  • can you create a stackblitz with a repro? I dont see any visible error in the code above. the observable should emit the values you sent to him. – Daniel Netzer Feb 22 '18 at 12:29
  • I got the issue and fix the problem, 1st issue is i had not called the anywhere in the app and 2nd i had to create another error log service to raise an observer or event to notify component which is called by error handler service. – Sunilsingh Rathore Feb 23 '18 at 09:50

3 Answers3

1

Method with Following format can give an output of service execution is successful or not. Hope the following code will help you

   //Code in service.ts
   @Injectable()
    export class ErrorHandlerService implements ErrorHandler {
        public apiError: Subject<any> = new BehaviorSubject(false);
        apiError$ = this.apiError.asObservable();
        constructor(private errorLogService: ErrorLogService
        ) { }

        private handleError(error) {
             return Observable.throw(error.json().msg || 'Server error');
        }
        _forgotPassword(userId, passwords, isResetPwd) {
            return this.http.post(this.forgotPasswordUrl,
                {
                    userId: userId,
                    passwords: passwords,
                    isResetPwd: isResetPwd
                })
                .map(res => res.json())
                .catch(this.handleError);
        }
    }

 //Code in component class file

  this.errorHandlerService._forgotPassword(userId, passwords, isResetPwd).
  subscribe(data => {
    // Code here.....
   });
vijesh
  • 1,115
  • 1
  • 11
  • 27
  • This can be general use case where we can capture error on every http request and handle it independently, but according to my question exception is already thrown and captured in the error handler service, now i need to pass this error to component so that component can show a dialog to the user with the error no. – Sunilsingh Rathore Feb 22 '18 at 12:23
  • @SunilsinghRathore I think using event emitter you can resolve this problem. Using event emitter you can identify on the component file, when the error is thrown on service. Please go through the following link. https://stackoverflow.com/questions/34700438/global-events-in-angular – vijesh Feb 23 '18 at 08:53
  • I got the issue and fix the problem, 1st issue is i had not called the anywhere in the app and 2nd i had to create another error log service to raise an observer or event to notify component which is called by error handler service. – Sunilsingh Rathore Feb 23 '18 at 09:50
0

This is how i have fixed it...

app.component.html

<error-log></error-log>

error-log.component

import { Component, OnInit } from '@angular/core';
import { ErrorLogService } from './error-log.service';

@Component({
  selector: 'error-log',
  templateUrl: './error-log.component.html',
  styleUrls: ['./error-log.component.scss']
})
export class ErrorLogComponent implements OnInit {

  constructor(private errorLogService: ErrorLogService) { }

  ngOnInit() {
    this.errorLogService.apiEvent.subscribe(data =>{

            alert("error in errorlog component through errorLogService event emitter = " + data);
          })

          this.errorLogService.apiError$.subscribe(data =>{
            alert("error in errorlog component errorLogService  = " + data);
          })
  }

}

error-handler.service

import { Injectable, ErrorHandler} from '@angular/core';
import { ErrorLogService } from './error-log.service';

    @Injectable()
    export class ErrorHandlerService implements ErrorHandler {
      constructor(private errorLogService: ErrorLogService
      ) {}

      handleError(error) {
        this.errorLogService.setError(error);
      };}

error-log.service

import { Injectable, ErrorHandler, EventEmitter, Output} from '@angular/core';
import { EventListener } from '@angular/core/src/debug/debug_node';
import { ReplaySubject} from 'rxjs/Rx';

@Injectable()
export class ErrorLogService  {
  public apiError: ReplaySubject<any> = new ReplaySubject();
  public apiEvent:EventEmitter<any> = new EventEmitter();
  public apiError$ = this.apiError.asObservable();
  constructor() {
    // super();
  }

  setError(error){
    this.apiEvent.emit(error);  
     this.apiError.next(error); 
    // super.handleError(error);
    console.log("ERROR = " + error);
  } }

No idea why i cant raise an event directly from error-handler.service

-2

if you initialize the component after the service recieve the errors then he can only emit errors that's being recieved after his init.

user ReplaySubject to emit all previous errors aswell

@Injectable()
export class ErrorHandlerService implements ErrorHandler {
  public apiError: ReplaySubject<any> = new ReplaySubject();
  apiError$ = this.apiError.asObservable();
  constructor(private errorLogService: ErrorLogService
  ) {}

  handleError(error) {
    this.apiError.next(error); 
    console.log("ERROR = " + error);
  };}
Daniel Netzer
  • 2,151
  • 14
  • 22