scttcper / ngx-toastr

🍞 Angular Toastr
https://ngx-toastr.vercel.app
MIT License
2.5k stars 359 forks source link

Tostr messages not working. Script error in browser console. #137

Closed harikrishnan-u01 closed 7 years ago

harikrishnan-u01 commented 7 years ago

Hi,

I followed the instructions to setup toastr as per the readme. Am using Angular version 4.1.3. ngx-toastr version is 5.2.4

this.toastrService.success('Hello world!', 'Toastr fun!');

The above line is throwing the following exception in browser console:

dom-portal-host.js:45 Uncaught TypeError: Cannot read property 'attachView' of undefined at DomPortalHost.attachComponentPortal (dom-portal-host.js:45) at DomPortalHost.BasePortalHost.attach (portal.js:47) at OverlayRef.attach (overlay-ref.js:10) at ToastrService._buildNotification (toastr-service.js:152) at ToastrService.success (toastr-service.js:25)

Any help is greatly appreciated.

Thanks, Hari

scttcper commented 7 years ago

Can you show us the ng module where you're importing toastrmodule

scttcper commented 7 years ago

Also a bit more on where you're using toastr service? In a component or service?

harikrishnan-u01 commented 7 years ago

Hi @scttcper ,

Thanks for the reply.

My scenario is that I want to show a toastr error message when some exception occur in the application. For this I implemented a GlobalExceptionHandler which will catch the exception and invoke the toastr service.

PFB the code I wrote:

` //global.error.handler.service.ts

import { ErrorHandler, Injectable, Injector} from '@angular/core'; import {ToastrMessageService} from './toastr.service';

@Injectable() export class GlobalErrorHandler implements ErrorHandler { private toastrService; constructor(injector:Injector) { this.toastrService = injector.get(ToastrMessageService); }

handleError(error) {
    this.toastrService.error('Some error occurred', 'Error occurred');

    throw error;
}

}

//toastr.service.ts

import {Injectable} from '@angular/core'; import { ToastrService } from 'ngx-toastr';

@Injectable() export class ToastrMessageService { constructor( private toastrService: ToastrService ) {

}

showError(message, heading) {
    if(message){
        this.toastrService.error(message, heading);
    }
}

}`

Hope this helps.

trevor-hackett commented 7 years ago

I've implemented something like this before. Here is what I've done:

app.error-handler.ts:

import { ErrorHandler, Inject, Injector, NgZone, isDevMode } from "@angular/core";
import { Response } from "@angular/http";
import { ToastrService } from "ngx-toastr";

import * as Raven from 'raven-js'

export class AppErrorHandler implements ErrorHandler {
    constructor(@Inject(NgZone) private ngZone: NgZone, @Inject(Injector) private injector: Injector) { }

    private get toastr(): ToastrService {
        return this.injector.get(ToastrService);
    }

    public handleError(error: any): void {
        this.ngZone.run(() => {
            let errorTitle = 'Error';
            let errMsg = 'An unexpected error ocurred';

            if (error instanceof Response) {
                const contentType = error.headers.get("Content-Type")

                if (contentType && contentType == "application/json") {
                    const body = error.json();
                    errorTitle = body.message || errorTitle;
                    errMsg = body.detailedMessage || JSON.stringify(body);
                } else {
                    errMsg = error.text();
                }
            }
            this.toastr.error(errMsg, errorTitle);
        });

        if (!isDevMode())
            Raven.captureException(error.originalError || error);
        else
            throw error;
    }
}

And then in app.module.ts:

@NgModule({
  // ... other imports, declarations, etc.
  providers: [
    { provide: ErrorHandler, useClass: AppErrorHandler },
    // ... other providers
  ]
})
export class AppModule {}

This is very similar to what you're doing. I'm not sure if NgZone is needed or not, it was working for HTTP error without it, but I decided to add it anyways, just in case.

harikrishnan-u01 commented 7 years ago

Hi @yarrgh ,

I emulated your code snippet and it worked like a charm. You made my day :)

Thanks, Hari

trevor-hackett commented 7 years ago

Glad it worked for you!

scttcper commented 7 years ago

@yarrgh the dependency injection wizard. I'll have to setup sentry in my app that way.

Silva-Macaneta commented 6 years ago

@yarrgh wow... thank you so much, i was losing hope.

chinnarao commented 5 years ago

i got the different error, so something is fishy, please owner look at this sir?

app.global.errorhandler.ts:20 Error: Uncaught (in promise): TypeError: Cannot read property 'create' of undefined TypeError: Cannot read property 'create' of undefined at ToastrService.push../node_modules/ngx-toastr/fesm5/ngx-toastr.js.ToastrService._buildNotification (ngx-toastr.js:1163) at ToastrService.push../node_modules/ngx-toastr/fesm5/ngx-toastr.js.ToastrService._preBuildNotification (ngx-toastr.js:1114) at ToastrService.push../node_modules/ngx-toastr/fesm5/ngx-toastr.js.ToastrService.error (ngx-toastr.js:906) at AppGlobalErrorhandler. (app.global.errorhandler.ts:21) at step (custom-http-client.ts:8) at Object.next (custom-http-client.ts:8) at custom-http-client.ts:8 at new ZoneAwarePromise (zone.js:891) at push../src/app/_error/app.global.errorhandler.ts.__awaiter (custom-http-client.ts:8) at AppGlobalErrorhandler.push../src/app/_error/app.global.errorhandler.ts.AppGlobalErrorhandler.handleError (app.global.errorhandler.ts:19) at ToastrService.push../node_modules/ngx-toastr/fesm5/ngx-toastr.js.ToastrService._buildNotification (ngx-toastr.js:1163) at ToastrService.push../node_modules/ngx-toastr/fesm5/ngx-toastr.js.ToastrService._preBuildNotification (ngx-toastr.js:1114) at ToastrService.push../node_modules/ngx-toastr/fesm5/ngx-toastr.js.ToastrService.error (ngx-toastr.js:906) at AppGlobalErrorhandler. (app.global.errorhandler.ts:21) at step (custom-http-client.ts:8) at Object.next (custom-http-client.ts:8) at custom-http-client.ts:8 at new ZoneAwarePromise (zone.js:891) at push../src/app/_error/app.global.errorhandler.ts.awaiter (custom-http-client.ts:8) at AppGlobalErrorhandler.push../src/app/_error/app.global.errorhandler.ts.AppGlobalErrorhandler.handleError (app.global.errorhandler.ts:19) at resolvePromise (zone.js:814) at new ZoneAwarePromise (zone.js:894) at push../src/app/_error/app.global.errorhandler.ts.awaiter (custom-http-client.ts:8) at AppGlobalErrorhandler.push../src/app/_error/app.global.errorhandler.ts.AppGlobalErrorhandler.handleError (app.global.errorhandler.ts:19) at dispatchEvent (core.js:7714) at core.js:8154 at HTMLButtonElement. (platform-browser.js:988) at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:421) at Object.onInvokeTask (core.js:3811) at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:420)