2

I currently have a module setup like below (exerpt);

AppModule

  RoutingModule
    AuthRouteGuard

  AuthModule
    LoginFormComponent
    AuthService        

I have defined my AuthService (responsible for handling user authentication and provides a method for determining whether the current user is authenticated) as a provider in my AuthModule;

// auth.module.ts - uses https://github.com/auth0/angular2-jwt

export function authHttpServiceFactory(http: Http, options: RequestOptions) {
  return new AuthHttp(new AuthConfig({
    tokenName: jwtLocalStorageKey
  }), http, options);
}

export let authHttpServiceProvider = {
  provide: AuthHttp,
  useFactory: authHttpServiceFactory,
  deps: [Http, RequestOptions]
};

@NgModule({
  imports: [
    CommonModule,
    FormsModule,
    ReactiveFormsModule
  ],
  exports: [AuthComponent],
  declarations: [AuthComponent, LoginComponent, RegisterComponent],
  providers: [
    AuthService,
    authHttpServiceProvider
  ]
})
export class AuthModule { }

I can use this service with no problem within its sibling LoginFormComponent. When I attempt to use the AuthService within the AuthRouteGuard class in the RoutingModule however I get the following error;

Error: Invalid provider for the NgModule 'AuthModule' - only instances of Provider and Type are allowed, got: [?undefined?, ...]

I have the AuthModule imported within the RoutingModule. The error above occurs as soon as the AuthService is defined as a dependency for the AuthRouteGuard;

export class AuthRouteGuard implements CanActivate {
  constructor(
    private router: Router,
    private authService: AuthService // Removing this injection removes the error
  ) {}

  canActivate() {
    // @todo: if not authenticated
    this.router.navigate(['/login']);

    return true;
  }
}

What am I missing here, and why would injecting the service in the constructor cause an invalid provider error that does not occur when that injection is removed?

Edit - Same error occurs if the authHttpServiceProvider provider is removed altogether, so the AuthModule module looks like;

@NgModule({
  imports: [
    CommonModule,
    FormsModule,
    ReactiveFormsModule
  ],
  exports: [AuthComponent],
  declarations: [AuthComponent, LoginComponent, RegisterComponent],
  providers: [
    AuthService
  ]
})
export class AuthModule { }
Roman C
  • 49,761
  • 33
  • 66
  • 176
James Crinkley
  • 1,398
  • 1
  • 13
  • 33

2 Answers2

0

Add authHttpServiceProvider to imports of the module. It's exported to global and not available to module. So you can't provide the service because you have unknown provider to the module.

@NgModule({
  imports: [
    CommonModule,
    FormsModule,
    ReactiveFormsModule
  ],
  exports: [AuthComponent],
  declarations: [AuthComponent, LoginComponent, RegisterComponent],
  providers: [
    AuthService
  ]
})
export class AuthModule { 
Roman C
  • 49,761
  • 33
  • 66
  • 176
  • Import into the `AuthModule`? That can't be true because if I remove the usage in the `RoutingModule` it works fine in the `LoginFormComponent` in the `AuthModule`. – James Crinkley Mar 19 '17 at 13:30
  • How does `RoutingModule` know about the provider? If you remove the module then you remove wrong provider. It's a solution. – Roman C Mar 19 '17 at 13:47
  • If I strip out everything related to the auth provider (so the only provider in the `AuthModule` is the `AuthService` the same error occurs, so it is not related to that. – James Crinkley Mar 19 '17 at 14:02
  • if you do something that is not working, then of course it doesn't work. You are doing wrong. – Roman C Mar 19 '17 at 14:06
  • That doesn't even make any sense.. I'm saying that if I completely remove the provider that you say is causing it the same error occurs, so the error cannot be related to that provider. – James Crinkley Mar 19 '17 at 14:07
  • If you have a problem with one thing and you remove another it doesn't help you with the first one. You comment doesn't make sense. – Roman C Mar 19 '17 at 14:10
  • Your answer above states that I need to add `authHttpServiceProvider` to the imports to fix it, because the module has an unknown provider. If I remove that provider altogether (that is not even being used anywhere yet) and the same error occurs, then it is physically impossible for that provider to be the cause of the issue. All I have now is a module that has a single provider (AuthService) and I cannot even import that within a service in a different module. – James Crinkley Mar 19 '17 at 14:12
  • That's right if you removing the provider the same error occurs. – Roman C Mar 19 '17 at 14:19
  • I have also added your module. If the service you can provide then it should find the provider in this module. – Roman C Mar 19 '17 at 14:24
  • I've solved it, but frustratingly the error is not at all indicative of the underlying error.. – James Crinkley Mar 19 '17 at 14:28
  • You didn't post `AuthService` so it was impossible to help you. – Roman C Mar 19 '17 at 14:35
0

The actual problem was within the AuthService itself.

AuthModule defined a constant;

export const jwtKey = 'jwt';

Which was being imported into the AuthService and used;

import { jwtKey } from '../auth.module';

For some reason if I remove this import everything works fine.

James Crinkley
  • 1,398
  • 1
  • 13
  • 33