1

I tried to follow this tutorial: http://jasonwatmore.com/post/2017/06/25/angular-2-4-alert-toaster-notifications

I have a problem with the routing. When i use router in my constructor, I get an parse Error.

notification.service.ts

import {Injectable, Injector} from '@angular/core';
import {NavigationStart, Router} from '@angular/router';
import {Observable} from 'rxjs';
import {Subject} from 'rxjs/Subject';

import {Notification, NotificationType} from '../models/notification';

@Injectable()
export class NotificationService {
    private subject = new Subject<Notification>();
    private keepAfterRouteChange = false;
    
    constructor(private router: Router) {
        // clear notification messages on route change unless 'keepAfterRouteChange' flag is true
        router.events.subscribe(event => {
            if (event instanceof NavigationStart) {
                if (this.keepAfterRouteChange) {
                    // only keep for a single route change
                    this.keepAfterRouteChange = false;
                } else {
                    // clear notification messages
                    this.clear();
                }
            }
        });
    }

    getNotification(): Observable<any> {
        return this.subject.asObservable();
    }

    success(message: string, keepAfterRouteChange = false) {
        this.notification(NotificationType.Success, message, keepAfterRouteChange);
    }

    error(message: string, keepAfterRouteChange = false) {
        this.notification(NotificationType.Error, message, keepAfterRouteChange);
    }

    info(message: string, keepAfterRouteChange = false) {
        this.notification(NotificationType.Info, message, keepAfterRouteChange);
    }

    warn(message: string, keepAfterRouteChange = false) {
        this.notification(NotificationType.Warning, message, keepAfterRouteChange);
    }

    notification(type: NotificationType, message: string, keepAfterRouteChange = false) {
        this.keepAfterRouteChange = keepAfterRouteChange;
        this.subject.next(<Notification>{type: type, message: message});
    }

    clear() {
        // clear notifications
        this.subject.next();
    }
}
Uncaught Error: Provider parse errors:
    Cannot instantiate cyclic dependency! ApplicationRef ("[ERROR ->]"): in NgModule AppModule in ./AppModule@-1:-1 
    at NgModuleProviderAnalyzer.parse (compiler.js:19549)
    at NgModuleCompiler.compile (compiler.js:20138)
    at JitCompiler._compileModule (compiler.js:34436)
    at eval (compiler.js:34367)
    at Object.then (compiler.js:474)
    at JitCompiler._compileModuleAndComponents (compiler.js:34365)
    at JitCompiler.compileModuleAsync (compiler.js:34259)
    at CompilerImpl.compileModuleAsync (platform-browser-dynamic.js:239)
    at PlatformRef.bootstrapModule (core.js:5551)
    at eval (main.ts:11)

I tried to fix this with an Injector, but than an other error occured

constructor(private injector: Injector) {
  this.router.events.filter(event => event instanceof NavigationStart).subscribe(
  (event: NavigationStart) => {
    ...
  });
}

public get router(): Router {
  return this.injector.get(Router);
}
RangeError: Maximum call stack size exceeded
    at StaticInjector.get (core.js:1109)
    at resolveNgModuleDep (core.js:10837)
    at _createClass (core.js:10882)
    at _createProviderInstance$1 (core.js:10848)
    at resolveNgModuleDep (core.js:10833)
    at _callFactory (core.js:10907)
    at _createProviderInstance$1 (core.js:10851)
    at resolveNgModuleDep (core.js:10833)
    at NgModuleRef_.get (core.js:12070)
    at NotificationService.get [as router] (notification.service.ts:27)

app.module.ts

@NgModule({
    declarations: [
        AppComponent,
        NotificationComponent,
        ...
    ],
    imports: [
        BrowserModule,
        FormsModule,
        HttpClientModule,
        AngularFontAwesomeModule,
        routing
    ],
    providers: [
        UserService,
        {
            provide: ErrorHandler,
            useClass: GlobalErrorHandler
        },
        GlobalErrorHandler,
        NotificationService
    ],
    bootstrap: [AppComponent]
})
export class AppModule {
}

The notification will be fired in error-handler.service.ts

@Injectable()
export class GlobalErrorHandler implements ErrorHandler {
    constructor(private notificationService: NotificationService) {
    }

    public handleError(error) {
        let message = "ERROR: ";
        if (error instanceof HttpErrorResponse) {
            message = message + error.status + ' ' + error.statusText;
            console.log(message);
            this.notificationService.error(message);
        } else {
            message = message + error;
            console.log(message);
        }
    }
}

Has somebody an idea what went wrong?

  • Are you sure that the issue is with constructor of NotificationService? – Sumeet Kale Feb 02 '18 at 17:27
  • Without the constructor there is no error. But keepAfterRouteChange does not work of course. The notification won't be deleted, after i change the route. – Peter Horitzer Feb 02 '18 at 17:32
  • 1
    As per both error it seems the dependency issue. There are dependency which are getting dependent on each other – Sumeet Kale Feb 02 '18 at 17:34
  • The problem is, I try to fire a notification from another service. I'll update the question – Peter Horitzer Feb 02 '18 at 17:37
  • Can you share the code where you are using this global error handler service? Because i have exact same alert Service and I have also used that alert service inside other service and it works fine. – Sumeet Kale Feb 02 '18 at 18:06
  • GlobalErrorHandler is my new ErrorHandler. It will be called from every error. See app.module.ts ``providers: [ { provide: ErrorHandler, useClass: GlobalErrorHandler }, GlobalErrorHandler, ]`` – Peter Horitzer Feb 02 '18 at 18:32
  • https://stackoverflow.com/a/52678220/6942012 check this one i answer here . thanks – Bhagvat Lande Oct 06 '18 at 10:58

0 Answers0