Question
I am trying to inject a service class into an Angular component, but Angular keeps throwing a "No provider for NameService" error.
Here is my code:
/// <reference path="../typings/angular2/angular2.d.ts" />
import { Component, View, bootstrap, NgFor } from "angular2/angular2";
import { NameService } from "./services/NameService";
@Component({
selector: 'my-app',
injectables: [NameService]
})
@View({
template:
'<h1>Hi {{name}}</h1>' +
'<p>Friends</p>' +
'<ul>' +
' <li *ng-for="#name of names">{{name}}</li>' +
'</ul>',
directives: [NgFor]
})
class MyAppComponent {
name: string;
names: Array<string>;
constructor(nameService: NameService) {
this.name = 'Michal';
this.names = nameService.getNames();
}
}
bootstrap(MyAppComponent);
export class NameService {
names: Array<string>;
constructor() {
this.names = ["Alice", "Aarav", "Martín", "Shannon", "Ariana", "Kai"];
}
getNames() {
return this.names;
}
}
What causes this error, and how should the service be registered so Angular can inject it into the component correctly?
Short Answer
By the end of this page, you will understand what Angular's "No provider" error means, how Angular dependency injection works, where services must be registered, and how to correctly inject a service like NameService into a component.
Concept
Angular uses a system called dependency injection (DI) to create and supply objects such as services.
When you write this constructor:
constructor(nameService: NameService) {}
Angular reads it as: "This component depends on an instance of NameService."
Angular can only create that service if it knows how to provide it. That is what a provider does.
A provider is Angular's registration record for a service. Without a provider, Angular does not know:
- whether the service is allowed to be created
- where it should be created
- which instance should be shared
That is why Angular throws:
No provider for NameService
In older Angular 2 syntax, services were registered using providers or in very early builds appInjector. Using the wrong metadata property such as injectables can cause Angular to ignore the service registration entirely.
In your code, the main issue is that injectables is not the correct way to register the service for the Angular version expected by this pattern. Angular therefore sees the constructor dependency, tries to resolve , and fails.
Mental Model
Think of Angular dependency injection like a tool desk in a workshop.
- Your component is a worker.
NameServiceis a tool.- Angular is the person managing the tool desk.
When the worker says, "I need a NameService", Angular checks the desk.
- If the tool is registered there, Angular hands it over.
- If the tool is not registered, Angular says: "No provider for NameService."
So the problem is usually not the constructor itself. The problem is that Angular's tool desk does not know about that tool yet.
Syntax and Examples
The core idea is:
- Create a service class.
- Register it with Angular using a provider.
- Request it in the constructor.
Service
export class NameService {
private names: string[] = ["Alice", "Aarav", "Martín", "Shannon", "Ariana", "Kai"];
getNames(): string[] {
return this.names;
}
}
Component with provider registration
import { Component, View, bootstrap, NgFor } from "angular2/angular2";
import { NameService } from "./services/NameService";
@Component({
selector: 'my-app',
providers: [NameService]
})
@View({
template:
+
+
+
+
,
: []
})
{
: ;
: [];
() {
. = ;
. = nameService.();
}
}
();
Step by Step Execution
Consider this simplified version:
class NameService {
getNames() {
return ["Alice", "Kai"];
}
}
@Component({
selector: 'my-app',
providers: [NameService]
})
class MyAppComponent {
names: string[];
constructor(nameService: NameService) {
this.names = nameService.getNames();
}
}
What happens step by step
- Angular starts creating
MyAppComponent. - Angular reads the constructor and sees that it needs a
NameService. - Angular checks the component's
providersarray. - It finds
NameServicethere. - Angular creates an instance of
NameService. - Angular passes that instance into the constructor.
- The constructor runs
nameService.getNames().
Real World Use Cases
Dependency injection and service providers are used everywhere in Angular apps.
API services
constructor(userService: UserService) {}
A service fetches users from a backend.
Shared application state
A cart service can be shared across product pages and checkout pages.
Validation and formatting
A service can centralize logic like date formatting, currency conversion, or form validation.
Authentication
An AuthService might store login status, tokens, and user profile information.
Logging and error reporting
Apps often inject a logging service to capture errors consistently.
In all of these cases, the service must be properly registered with Angular before it can be injected.
Real Codebase Usage
In real Angular codebases, developers usually register services at the appropriate scope.
Root-level shared services
Used when one instance should be shared across the app.
Examples:
- authentication
- API clients
- configuration
- global state
In older Angular versions this could be done at bootstrap:
bootstrap(MyAppComponent, [NameService]);
Component-level services
Used when each component should get its own instance.
@Component({
selector: 'user-panel',
providers: [UserPanelService]
})
Common patterns
Guard clauses
Services often validate input early:
getUser(id: number) {
if (!id) {
throw new Error('User id is required');
}
}
Wrapping reusable logic
Instead of putting data logic in the component:
Common Mistakes
Here are common reasons beginners see "No provider" errors.
1. Using the wrong metadata property
Broken:
@Component({
selector: 'my-app',
injectables: [NameService]
})
Correct:
@Component({
selector: 'my-app',
providers: [NameService]
})
If Angular does not recognize the property, the service is never registered.
2. Forgetting to register the service anywhere
Broken:
constructor(nameService: NameService) {}
with no providers and no bootstrap registration.
Fix: add the service to providers or register it at bootstrap.
3. Importing the wrong class path
If the import path is wrong, Angular may not be using the class you think it is.
import { } ;
Comparisons
Here are some useful comparisons around Angular service injection.
| Concept | What it does | When to use it |
|---|---|---|
providers: [NameService] | Registers a service for dependency injection | When the component or its children need the service |
bootstrap(MyAppComponent, [NameService]) | Registers a root-level service | When the whole app should share one instance |
Constructor parameter nameService: NameService | Requests the dependency | When the component needs to use the service |
| Plain import only | Makes the class available in the file | Not enough for DI by itself |
Import vs provider
import { NameService } from "./services/NameService";
This only tells TypeScript where the class is.
Cheat Sheet
// 1. Create the service
export class NameService {
getNames(): string[] {
return ["Alice", "Kai"];
}
}
// 2. Register the service in the component
@Component({
selector: 'my-app',
providers: [NameService]
})
class MyAppComponent {
constructor(nameService: NameService) {}
}
// 3. Or register it at bootstrap/root level
bootstrap(MyAppComponent, [NameService]);
Rules to remember
importdoes not register a service for DI.- Angular can only inject services that have a provider.
providersis the key Angular looks for.- Constructor injection requests dependencies.
- Root registration shares one instance more broadly.
- Component registration can create local instances.
FAQ
Why does Angular say "No provider for NameService"?
Because Angular sees that the component wants a NameService, but it cannot find a registered provider telling it how to create one.
Is importing the service enough?
No. Importing only makes the class available in the file. You must also register it as a provider.
Should I use providers in the component or at bootstrap?
Use component-level registration when you want a local instance. Use bootstrap or root-level registration when the service should be shared more widely.
What is the difference between a provider and a service?
A service is the class itself. A provider is Angular's registration that tells the DI system how to supply that service.
Why is injectables not working here?
Because Angular expects provider registration using the correct API for that version. If the metadata key is not recognized, Angular ignores it.
Can a component work without dependency injection?
Yes, but DI is the standard Angular pattern for reusable services and shared logic.
Does each component get a new service instance?
It depends on where the provider is registered. Component-level registration can create separate instances, while root-level registration usually shares one instance.
Mini Project
Description
Build a small Angular component that displays a list of names from a service. This project demonstrates the full dependency injection flow: defining a service, registering it correctly, injecting it into a component, and rendering the returned data in the template.
Goal
Create a component that injects NameService and shows a list of names without triggering a provider error.
Requirements
- Create a
NameServiceclass that returns an array of names. - Register the service so Angular can inject it.
- Inject the service into a component constructor.
- Store the returned names in a component property.
- Render the names in the template using
NgFor.
Keep learning
Related questions
@Directive vs @Component in Angular: Differences, Use Cases, and When to Use Each
Learn the difference between @Directive and @Component in Angular, including use cases, examples, and when to choose each.
Angular (change) vs (ngModelChange): What’s the Difference?
Learn the difference between Angular (change) and (ngModelChange), when each fires, and which one to use in forms and inputs.
Angular @ViewChild Returning Undefined: Lifecycle, Child Components, and Fixes
Learn why Angular @ViewChild can be undefined, when it becomes available, and how to access child components correctly using lifecycle hooks.