Angular 2 - No provider for Service
Solution 1
It was a configuration issue after all, and a completely elusive one at that.
Per the ang2 style guide, I had my main.ts one folder up from my main app folder, and in systemjs.config
I had to declare the main for app as '../main.js'
. When I moved the main file to the root app folder and changed the package declaration in systemjs to 'main.js'
it worked.
The odd thing is everything else worked, right up until I try to utilize hierarchical dependency injection.
Solution 2
To All future readers - and this is correct for angular 2.0.0 rc-4:
make sure that you follow the below folder structure:
root: index.html package.json systemjs.config.js tsconfig.json (if using TypeScript) typings.json app (folder): - main.js (the root script for your app) - app.component.js (the root component for the entire app)
This is crucial for the hierarchical injection to properly scope and identify providers.
Also, and this is very important - if still encountering problems and you are using TypeScript or any other transpiled language- delete any artifacts which your transpiler produces for every associated class in the problematic object graph - this, and the OP's answer eventually helped in my case (*.map.js and *.js files deleted and re-transpiled).
Solution 3
For me, some references to the "services" folder were "Services". When I made them all "services" (lower case), it worked.
For example:
import {ApiService} from "./Services/api.service";
didn't work, but this worked:
import {ApiService} from "./services/api.service";
Solution 4
Injecting something on the app
level is done in bootstrap
:
main.ts
:
import { TestService } from '../shared/test.service';
bootstrap(AppComponent, [
APP_ROUTER_PROVIDERS, TestService
])
Daynil
Updated on June 17, 2022Comments
-
Daynil almost 2 years
I've been trying to troubleshoot a strange problem with angular 2 where it isn't detecting my provider declaration, but nothing is working. I can't even replicate it in plunkr.
I'm using angular 2 rc 3 with router 3.0 alpha.8.
Error message is:
ORIGINAL EXCEPTION: No provider for TestService!
app.routes.ts:
import { provideRouter, RouterConfig } from '@angular/router'; import { HomeComponent } from './app/home/home.component'; import { LogInComponent } from './app/log-in/log-in.component'; import { SignUpComponent } from './app/sign-up/sign-up.component'; export const routes: RouterConfig = [ { path: '', component: HomeComponent }, { path: 'log-in', component: LogInComponent }, { path: 'sign-up', component: SignUpComponent } ]; export const APP_ROUTER_PROVIDERS = [ provideRouter(routes) ];
main.ts:
import { bootstrap } from '@angular/platform-browser-dynamic'; import { enableProdMode } from "@angular/core"; import { AppComponent } from './app/app.component'; import { APP_ROUTER_PROVIDERS } from './app.routes'; // enableProdMode(); bootstrap(AppComponent, [ APP_ROUTER_PROVIDERS ]) .catch(error => console.log(error));
app/app.component.ts:
import { Component } from '@angular/core'; import { ROUTER_DIRECTIVES } from '@angular/router'; import { TestService } from './shared/test.service'; @Component({ selector: 'my-app', template: ` <div id="menu"> <a [routerLink]="['/sign-up']"><button>Sign Up</button></a> </div> <router-outlet></router-outlet> `, directives: [ROUTER_DIRECTIVES], providers: [TestService] }) export class AppComponent { constructor() { } }
app/sign-up/sign-up.component.ts:
import { Component } from '@angular/core'; import { ROUTER_DIRECTIVES } from '@angular/router'; import { TestService } from '../shared/test.service'; @Component({ selector: 'sign-up', template: `<h1>Sign up!</h1>`, directives: [ROUTER_DIRECTIVES] }) export class SignUpComponent { constructor(private testService: TestService) { this.testService.test('works?'); } }
app/shared/test.service.ts:
import { Injectable } from '@angular/core'; @Injectable() export class TestService { constructor() { } test(message: string) { console.log(message); } }
So, I'm providing the testservice in the base component (app.component.ts) because I want all my components to access the same instance. However, when I navigate to sign-up, I get the no provider for testservice error. If I provide the TestService within the sign-up component, this then works:
import { Component, OnInit } from '@angular/core'; import { ROUTER_DIRECTIVES } from '@angular/router'; import { TestService } from '../shared/test.service'; @Component({ selector: 'sign-up', template: `<h1>Sign up!</h1>`, directives: [ROUTER_DIRECTIVES], providers: [TestService] }) export class SignUpComponent implements OnInit { constructor(private testService: TestService) { } ngOnInit() { } }
However, I need the same instance accessible throughout my app, so how can I inject this at the main component level?
I even tried replicating this app-level service providing with plunkr with the same version of everything, but it doesn't seem to give me the same error...