7

I'm trying to do the following in Angular 2 (typescript): For each error (especially errors from the backend server) - present the error to the user (in the UI) - in the main component (mainly since I do't want to write same code in each component).

Is it a simple way to do it? I guess what I need is a way to set an "error" member in the main component? How do I do it if I override ExceptionHandler?

thanx, Pavel.

6
  • See stackoverflow.com/questions/38882969/… and angular.io/docs/ts/latest/api/core/index/… You should be aware that not catching exceptions locally can leave your component in an undefined state. You might need to invoke change detection afterwards explicitely. See for example stackoverflow.com/questions/37793276/… Commented Aug 16, 2016 at 20:07
  • Hi Günter, My question is how do I make the ExceptionHandler change some state in the main app component (to present an error message in the UI)? Commented Aug 16, 2016 at 20:30
  • You can use a shared service where you update the state from the exception handler or emit events using observables and a component that updates the DOM (show error information) depending on the info from that service. Commented Aug 16, 2016 at 20:42
  • Hi Günter, If I understand correctly, you suggest: In ExceptionHandler - call MyService.setErrorState(true), then in main component add ngif calling MyService.getErrorState(). But who will call MyService.setErrorState(false) when moving to next page? Commented Aug 17, 2016 at 7:06
  • That depends on your requirements. Perhaps you want to wait until the user clicks "dismiss" or just a timeout so the message disappears after 10 seconds, ... Commented Aug 17, 2016 at 7:43

1 Answer 1

18
  1. Create NotificationService in shared directory

    import { Injectable } from '@angular/core';
    import { Message } from 'primeng/primeng';
    
    @Injectable()
    export class NotificationService {
        message: Message[];
    
        constructor() {
            this.message = [];
        }
    
        success(detail: string, summary?: string): void {
            this.message.push({
                severity: 'success', summary: summary, detail: detail
            });
        }
    
        info(detail: string, summary?: string): void {
            this.message.push({
                severity: 'info', summary: summary, detail: detail
            });
        }
    
        warning(detail: string, summary?: string): void {
            this.message.push({
                severity: 'warn', summary: summary, detail: detail
            });
        }
    
        error(detail: string, summary?: string): void {
            this.message.push({
                severity: 'error', summary: summary, detail: detail
            });
        }
    }
    
  2. create a custom ExceptionHandler (ErrorHandler in RC 6) in shared directory

    import { ErrorHandler, Inject } from '@angular/core';
    import { NotificationService } from './notification.service';
    
    
    export class CustomErrorHandler implements ErrorHandler {
    
        constructor(@Inject(NotificationService) private notificationService: NotificationService) {
        }
    
        handleError(error: any): void {
            this.showErrorInConsole(error);
            setTimeout(() => 
                this.notificationService.error(error.json().Message), 1);
        }
    
        private showErrorInConsole(error: any) :void {
            if (console && console.group && console.error) {
                console.group("Error Log");
                console.error(error);
                console.error(error.message);
                console.error(error.stack);
                console.groupEnd();
            }
        }
    }
    
  3. update AppModule for overriding default error handler

    import { GrowlModule } from 'primeng/primeng';
    ...
    import { NotificationService } from './shared/notification.service';
    import { CustomErrorHandler } from './shared/custom-error-handler';
    
    @NgModule({
        imports: [
            ...,
            GrowlModule // prime ng notification
        ],
        declarations: [
            ...
        ],
        providers: [
            ...,
            NotificationService, // added
            { provide: ErrorHandler, useClass: CustomErrorHandler } // overrride default error handler
        ],
        bootstrap: [AppComponent]
    })
    export class AppModule { }
    
  4. finally in AppComponent:

    import { Component } from '@angular/core';
    import { Message } from 'primeng/primeng';
    import { NotificationService } from './shared/notification.service';
    
    
    @Component({
        selector: 'my-app',
        template: `
            <p-growl [value]="getMessages()"></p-growl>
        `
    })
    export class AppComponent{
        constructor(private notification: NotificationService) {
        }
    
        getMessages(): Message[] {
            return this.notification.message;
        }
    }
    
Sign up to request clarification or add additional context in comments.

3 Comments

In case it helps anyone, I had to use the following in my template: <p-growl [(value)]="this.notificationService.messages"></p-growl> in order to get the binding to work correctly, notificationService being made a public member of the component.
Note that GrowlModule has now been deprecated. Use Toast instead. github.com/primefaces/primeng/issues/8328
Also worth using PrimeNG MessageService . Example: github.com/primefaces/primeng/blob/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.