0
votes

I use an AuthService and an AuthGuard to log in/log out users and guard routes. The AuthService is used in the AuthGuard as well as in a LoginComponent. The AuthGuard is used to guard routes via CanActivate. When I try to run the app I get the following error:

zone.js:522 Unhandled Promise rejection: No provider for AuthService! ; Zone: angular ; Task: Promise.then ; Value: NoProviderError {__zone_symbol__error: Error: DI Error
    at NoProviderError.ZoneAwareError 

I have checked that the LoginComponent and AuthGuard both import the AuthService and inject it into the components via the constructor. I have also checked that the AuthService is imported into the AppModule file and added to the providers array so it can be used as a singleton service.

Edited to add code samples:

My App module contains the following:

@NgModule({
    imports: [...],
    providers: [..., AuthService, AuthGuard, ...],
    declarations: [..., LoginComponent, EntryComponent ...],
    bootstrap: [EntryComponent]
})
export class AppModule {
}

AuthGuard:

import { Injectable } from '@angular/core';
import { CanActivate, Router, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { ApiConfig } from '../Api';

import { AuthService } from './authservice';

@Injectable()
export class AuthGuard implements CanActivate {
    constructor(
        private authService: AuthService,
        private router: Router,
        private config: ApiConfig
    ) { }

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {

        console.log(this.isAuthenticated());

        if (this.isAuthenticated()) {
            if (this.config.defined) {
                return true;
            } else {
                this.authService.setConfig();
                return true;
            }
        } else {
            this.router.navigate(['/Login']);
            return false;
        }
    }

    // Checks if user is logged in 
    isAuthenticated() {
        return this.authService.userLoggedIn();
    }
}

LoginComponent constructor:

constructor(
        private router: Router,
        private notifications: Notifications,
        private authService: AuthService
    ) {}

AuthService:

import { Injectable } from '@angular/core';
import { Http, Headers, RequestOptions } from '@angular/http';
import { Router } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { ApiConfig } from '../Api';

@Injectable()
export class AuthService {
    constructor(
        private http: Http,
        private router: Router,
        private config: ApiConfig
    ) {
        this.apiRoot = localStorage.getItem('apiRoot');
    }

    ...
}
2
Please provide the code. Service classes with constructor and where and how you provide and inject them.Günter Zöchbauer
AuthService should be provided in the AppModule using the providers array, not imports.Mihailo
@Mihailo sorry that was a typo on my end, meant to say providers array. It is not in the imports array. I will edit the questionnatmegs
@natmegs did you have this issue before implementing the AuthGuard?Mihailo
@GunterZochbauer I've edited the question to add some code samplesnatmegs

2 Answers

1
votes

In your app.component class @Component({}) decoration add a line that states:

providers: [AuthService]

This creates a singleton service for that service at that level. If you wanted to provide it at a more granular level you would provide (instantiate) it at that lower level.

Please see the first couple paragraphs in this official angular 2 documentation

1
votes

Turns out I didn't capitalize my AuthService import correctly in AuthGuard.....

import { AuthService } from './authservice';

should have been

import { AuthService } from './AuthService';

Note to self: imports are case sensitive