user630209
user630209

Reputation: 1207

No provider for AppComponent error on loading

@NgModule({
  declarations: [
    AppComponent
    , DesktopComponent

  ],
  imports: [
    BrowserModule,
    FormsModule,
    ReactiveFormsModule,
    HttpModule,
    AppRoutingModule,
    )
  ],
  providers: [LoginService, { provide: LocationStrategy, useClass: HashLocationStrategy } ,
    {
      provide: Http,
      useFactory: httpFactory,
      deps: [XHRBackend, RequestOptions, Router, AppComponent]
    }, MasterDataService, PersonService
  ],
  bootstrap: [AppComponent]

})
export class AppModule { }

Getting error Error: No provider for AppComponent! when added deps: [XHRBackend, RequestOptions, Router, AppComponent].

Have used this tutorial https://scotch.io/@kashyapmukkamala/using-http-interceptor-with-angular2 to implement a interceptor. Now I want to call a method in AppComponent from Inteceptor class.

This is the interceptor method where I had to call AppComponent logout method

 intercept(observable: Observable<Response>): Observable<Response> {
        return observable.catch((err, source) => {
            if (err.status == 401) {

               localStorage.clear();
             this.appComp.logout();

            } else {
                return Observable.throw(err);
            }
        });

In App Component Log out method

logout() {
        console.log(" logging out");
        this.authenticated = false;
        $('#wrapper').attr("style", "display:none");
        this.loginService.logout();
    } 

Upvotes: 2

Views: 5987

Answers (2)

hagner
hagner

Reputation: 1050

The approach you are trying to use here is not aligned with the Angular design principals, services should be designed as a seperate concern and should be reusable by different components and also testable. Therefor services should not try to interact with components directly. Instead, components should listen to responses or events from services and then decide how to react.

I recommend creating a generic notification service that can be used to send internal messages throughout your application. This service is not limited to sending messages from your interceptor to AppComponent but can be reused to communicate events in various part of your application.

Here is an example of a simple notification service, this service should be injected both in your interceptor and in the AppComponent:

import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';
import { Notification } from './notification';

@Injectable()
export class NotificationService {
    private notificationSubject = new Subject<Notification>();
    public notifications = this.notificationSubject.asObservable();

    notify(notification: Notification): void {
        this.notificationSubject.next(notification);
    }
}

The Notification class looks like this:

export class Notification {
    message: string;
    status: NotificationStatus;

    constructor(message?: string, status?: NotificationStatus) {
        this.message = message;
        this.status = status;
    }
}

export enum NotificationStatus {
    Success = 0,
    Loading = 1,
    Confirm = 2,
    Error = 3, 
    Unauthorized = 4
}

So when you want to send a message, inject the notification service and call the notify method:

if (err.status == 401) {
    this.notificationService.notify(new Notification('Unauthorized', NotificationStatus.Unauthorized));
    return Observable.empty();
}

Your AppComponent can then subscribe to events from your notification service:

this.notificationService.subscribe(notification => { 
    if(notification.status == NotificationStatus.Unauthorized) {
        //Handle any unauthorized errors here like and call logout() method
    }
});

Upvotes: 4

Vignesh
Vignesh

Reputation: 2386

In Providers why you are using 'AppComponent' you can't use Component in Providers

Try the below code:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import {HttpModule, Http, XHRBackend, RequestOptions} from '@angular/http';

import {AppComponent} from "./app.component";
import {httpFactory} from "./http.factory";

@NgModule({
    declarations: [
        AppComponent
    ],
    imports: [
        BrowserModule,
        FormsModule,
        HttpModule
    ],
    bootstrap: [AppComponent],
    providers: [
        {
            provide: Http,
            useFactory: httpFactory,
            deps: [XHRBackend, RequestOptions]
        }
    ]
})
export class AppModule { }

Upvotes: 0

Related Questions