Question
Angular Dependency Injection: Fix "Can't Resolve All Parameters for Component" Errors
Question
I built a basic Angular app, but I ran into an issue when injecting a service into one specific component. The same service injects correctly into three other components, but not this one.
Here is the service:
import { Injectable } from '@angular/core';
@Injectable()
export class MobileService {
screenWidth: number;
screenHeight: number;
constructor() {
this.screenWidth = window.outerWidth;
this.screenHeight = window.outerHeight;
window.addEventListener('resize', this.onWindowResize.bind(this));
}
onWindowResize(ev: Event) {
const win = ev.currentTarget as Window;
this.screenWidth = win.outerWidth;
this.screenHeight = win.outerHeight;
}
}
And here is the component where injection fails:
import { Component } from '@angular/core';
import { NgClass } from '@angular/common';
import { ROUTER_DIRECTIVES } from '@angular/router';
import { MobileService } from '../';
@Component({
moduleId: module.id,
selector: 'pm-header',
templateUrl: 'header.component.html',
styleUrls: ['header.component.css'],
directives: [ROUTER_DIRECTIVES, NgClass],
})
export class HeaderComponent {
mobileNav: boolean = false;
constructor(public ms: MobileService) {
console.log(ms);
}
}
The browser console shows this error:
EXCEPTION: Can't resolve all parameters for HeaderComponent: (?).
The service is already registered in the bootstrap function, so it has a provider. Why would Angular fail to inject it into this component while it works in the others?
Short Answer
By the end of this page, you will understand how Angular dependency injection figures out what to pass into a component constructor, why the error Can't resolve all parameters for component: (?) happens, and how import paths, metadata, and TypeScript configuration can cause it. You will also learn practical ways to diagnose and fix service injection problems in Angular apps.
Concept
Angular uses dependency injection (DI) to create objects like services and pass them into components automatically.
When Angular sees a constructor like this:
constructor(public ms: MobileService) {}
it tries to answer two questions:
- What dependency is being requested?
- Is there a provider registered for it?
To answer the first question, Angular relies on type metadata generated by TypeScript and decorators such as @Component() and @Injectable().
If Angular cannot determine the constructor parameter type, it often shows an error like:
Can't resolve all parameters for HeaderComponent: (?)
The (?) means Angular sees that there is a constructor parameter, but it cannot identify what token should be injected.
This usually happens for one of these reasons:
- The import points to the wrong symbol or a broken barrel export.
- The type metadata was not emitted correctly.
- The class being imported is
undefinedat runtime. - The service is missing
@Injectable()in cases where Angular needs metadata. - The parameter type is not a valid runtime token.
Mental Model
Think of Angular DI like a delivery system for packages.
- Your component constructor is the delivery request form.
MobileServiceis the package name.- Angular is the delivery worker.
- Providers are the warehouse where packages are stored.
If the form clearly says MobileService, Angular can pick it from the warehouse and deliver it.
But if the form is smudged, missing, or points to the wrong package, Angular sees only:
- “There is a package requested here…”
- “…but I cannot tell what it is.”
That is what the (?) means. Angular knows there is a constructor parameter, but it cannot read its identity clearly enough to inject it.
Syntax and Examples
Angular service injection usually looks like this:
import { Injectable } from '@angular/core';
@Injectable()
export class LoggerService {
log(message: string) {
console.log(message);
}
}
import { Component } from '@angular/core';
import { LoggerService } from './logger.service';
@Component({
selector: 'app-home',
template: `<button (click)="save()">Save</button>`
})
export class HomeComponent {
constructor(private logger: LoggerService) {}
save() {
this.logger.log();
}
}
Step by Step Execution
Consider this component:
import { Component } from '@angular/core';
import { MobileService } from '../mobile.service';
@Component({
selector: 'pm-header',
template: `Width: {{ ms.screenWidth }}`
})
export class HeaderComponent {
constructor(public ms: MobileService) {
console.log('Service instance:', ms);
}
}
Here is what happens step by step:
-
Angular starts creating
HeaderComponent. -
It reads the constructor:
constructor(public ms: MobileService) {} -
Angular checks the metadata for the constructor parameter type.
-
It sees that the parameter should be .
Real World Use Cases
Dependency injection is used throughout Angular applications.
1. Screen and device information
A service like MobileService can track screen size and expose responsive state to multiple components.
Examples:
- showing a mobile menu,
- changing layout for tablets,
- hiding sidebars on small screens.
2. API communication
Services often wrap HTTP requests:
constructor(private userService: UserService) {}
Used for:
- loading user profiles,
- sending form data,
- fetching product lists.
3. Shared application state
A service can hold state shared across components.
Examples:
- current logged-in user,
- theme settings,
- shopping cart contents.
4. Logging and analytics
A service may send logs or usage events.
Examples:
- track page views,
- record errors,
- measure feature usage.
5. Validation and utility logic
Services can centralize reusable business rules.
Examples:
Real Codebase Usage
In real Angular projects, developers commonly use DI with a few practical patterns.
Direct imports instead of fragile barrel imports
This is especially useful when debugging:
import { MobileService } from '../mobile.service';
instead of:
import { MobileService } from '../';
Shared singleton services
A service is often provided at a high level so many components can use the same instance.
Modern Angular commonly uses:
@Injectable({ providedIn: 'root' })
export class MobileService {}
Older Angular versions often register it in bootstrap or module providers.
Guard clauses with injected services
Developers often use services immediately to make decisions:
if (this.ms.screenWidth < 768) {
. = ;
}
Common Mistakes
Here are the most common reasons beginners see this error.
1. Importing from the wrong path
Broken code:
import { MobileService } from '../';
Why it fails:
../depends on anindex.tsbarrel.- If the barrel export is missing or incorrect, Angular may not get the actual class.
Safer version:
import { MobileService } from '../mobile.service';
2. Forgetting to provide the service
Broken code:
@Injectable()
export class MobileService {}
but no provider is registered anywhere.
Fix:
- add it to module providers,
- or use
providedIn: 'root'in newer Angular.
3. Missing @Injectable() on services
Comparisons
| Situation | What Angular knows | Typical Result |
|---|---|---|
| Correct service import + provider exists | Exact class/token | Injection works |
| Correct service import + no provider | Exact class/token, but unavailable | Provider error |
| Wrong or broken import | Parameter exists, but token unclear | Can't resolve all parameters: (?) |
Primitive constructor parameter like string | Not a service token by default | Injection error |
| Circular dependency | Token may become undefined at runtime | Injection or runtime error |
Direct import vs barrel import
| Approach | Example |
|---|
Cheat Sheet
// Service
import { Injectable } from '@angular/core';
@Injectable()
export class MobileService {}
// Component
import { Component } from '@angular/core';
import { MobileService } from './mobile.service';
@Component({
selector: 'app-header',
template: ''
})
export class HeaderComponent {
constructor(private mobileService: MobileService) {}
}
Quick rules
- Use
@Injectable()on services. - Make sure the service has a provider.
- Prefer direct imports when debugging DI issues.
- Avoid circular dependencies.
- Constructor parameter types must be valid injection tokens.
- In older Angular setups, ensure TypeScript decorator metadata is enabled.
Error hints
FAQ
Why does Angular show Can't resolve all parameters for component: (?)?
It means Angular sees a constructor parameter but cannot determine its dependency token at runtime.
Why would a service inject into some components but not one specific component?
That usually points to a file-specific issue such as a wrong import path, a circular dependency, or a broken barrel export in that component file.
What is the difference between No provider and Can't resolve all parameters?
No provider means Angular recognized the service type but could not find a provider. Can't resolve all parameters means Angular could not even identify the constructor parameter properly.
Can barrel files cause Angular DI errors?
Yes. If an index.ts barrel exports the wrong symbol or creates a circular dependency, Angular may receive undefined instead of the service class.
Should I always use @Injectable() on services?
Yes. It is good practice and required in many DI-related cases.
How do I fix this error first?
Start by using a direct import for the service, verify the provider registration, and check for circular imports.
Does TypeScript configuration affect Angular DI?
Yes, especially in older Angular setups. Missing decorator metadata settings can prevent Angular from reading constructor types.
Mini Project
Description
Build a small Angular feature with a ScreenService and a HeaderComponent that displays whether the app is in mobile mode. This project demonstrates correct service injection, safe imports, and how shared UI logic belongs in a service instead of being duplicated across components.
Goal
Create a component that injects a screen-related service and updates the UI based on window width.
Requirements
- Create a service that stores the current window width.
- Update the width value when the browser window is resized.
- Inject the service into a header component.
- Display a mobile or desktop label based on the current width.
- Use a direct import path for the service in the component.
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 formControl Error with Material Autocomplete: Why It Happens and How to Fix It
Learn why Angular says it cannot bind to formControl and how to fix Reactive Forms setup with Angular Material Autocomplete.