Introduction
Angular's dependency injection system resolves providers from the injector tree. When a requested service or token is not found in any injector, Angular throws a NullInjectorError or provider resolution failure.
Symptoms
NullInjectorError:
ERROR NullInjectorError: No provider for DataService!
at NullInjector.get (core.js:824)
at R3Injector.get (core.js:891)Provider not found:
ERROR Error: Uncaught (in promise): NullInjectorError: No provider for HttpClient!
NullInjectorError: No provider for HttpClient!Injection token error:
ERROR NullInjectorError: No provider for InjectionToken API_CONFIG!Circular dependency:
ERROR Error: Cannot instantiate cyclic dependency! (ComponentA -> ComponentB -> ComponentA)Common Causes
- 1.Missing provider - Service not registered in any module
- 2.Module import missing - HttpClientModule not imported
- 3.Wrong provider scope - Service in wrong module (root vs feature)
- 4.InjectionToken not provided - Token missing providedIn
- 5.Circular dependency - Services depend on each other
- 6.Lazy module isolation - Service in lazy module not accessible
- 7.@Inject decorator wrong - Incorrect token injection
Step-by-Step Fix
Step 1: Identify Missing Provider
```typescript // Error indicates which provider is missing ERROR NullInjectorError: No provider for DataService!
// Check where DataService is defined // Find the service file @Injectable() export class DataService { }
// Problem: @Injectable() without providedIn // Fix: Add providedIn or add to module providers
@Injectable({ providedIn: 'root' // Singleton across app }) export class DataService { }
// Or add to module @NgModule({ providers: [DataService] // Registered in this module }) export class AppModule { } ```
Step 2: Check HttpClientModule Import
```typescript // Common error: HttpClient not provided ERROR NullInjectorError: No provider for HttpClient!
// Fix: Import HttpClientModule import { HttpClientModule } from '@angular/common/http';
@NgModule({ imports: [ HttpClientModule, // Required for HttpClient // ... ] }) export class AppModule { }
// For standalone components (Angular 14+) import { provideHttpClient } from '@angular/common/http';
@Component({ standalone: true, imports: [HttpClientModule], providers: [provideHttpClient()] }) export class MyComponent { } ```
Step 3: Check Module Imports
```typescript // Service in feature module, used in another module @NgModule({ providers: [FeatureService] }) export class FeatureModule { }
// AppModule doesn't import FeatureModule @NgModule({ imports: [ /* missing FeatureModule */ ] }) export class AppModule { }
// Fix: Import the module @NgModule({ imports: [ FeatureModule, // Now FeatureService available ] }) export class AppModule { }
// Or export the service from FeatureModule @NgModule({ providers: [FeatureService], exports: [FeatureService] // Export service }) export class FeatureModule { } ```
Step 4: Check Provider Scope
```typescript // providedIn: 'root' vs providedIn: FeatureModule
// Root scope - singleton across entire app @Injectable({ providedIn: 'root' }) export class GlobalService { }
// Feature module scope - only in that module @Injectable({ providedIn: FeatureModule }) export class FeatureScopedService { }
// No providedIn - must be added to providers @Injectable() // Missing providedIn export class UnprovidedService { }
// Fix: Add to module providers @NgModule({ providers: [UnprovidedService] }) export class SomeModule { }
// Check: providedIn requires module to be imported where service is used ```
Step 5: Fix InjectionToken Providers
```typescript // InjectionToken without provider export const API_CONFIG = new InjectionToken<string>('api.config');
// Component injects it constructor(@Inject(API_CONFIG) private config: string) { }
// Error: No provider for InjectionToken api.config!
// Fix: Provide the token @NgModule({ providers: [ { provide: API_CONFIG, useValue: 'https://api.example.com' } ] }) export class AppModule { }
// Or use providedIn with factory export const API_CONFIG = new InjectionToken<string>('api.config', { providedIn: 'root', factory: () => 'https://api.example.com' }); ```
Step 6: Resolve Circular Dependencies
```typescript // Circular dependency error @Injectable() export class ServiceA { constructor(private serviceB: ServiceB) { } }
@Injectable() export class ServiceB { constructor(private serviceA: ServiceA) { } }
// ERROR: Cannot instantiate cyclic dependency!
// Fix: Use forwardRef or refactor @Injectable() export class ServiceA { constructor(@Inject(forwardRef(() => ServiceB)) private serviceB: ServiceB) { } }
// Better: Refactor to remove circular dependency // Extract shared functionality to separate service @Injectable() export class SharedService { }
@Injectable() export class ServiceA { constructor(private shared: SharedService) { } }
@Injectable() export class ServiceB { constructor(private shared: SharedService) { } } ```
Step 7: Handle Lazy Module Services
```typescript // Service in lazy-loaded module @NgModule({ providers: [LazyService] }) export class LazyModule { }
// Lazy loaded module creates its own injector // LazyService NOT available in AppModule
// Fix 1: Use providedIn: 'root' for shared services @Injectable({ providedIn: 'root' }) export class LazyService { }
// Fix 2: Import lazy module eagerly if service needed elsewhere @NgModule({ imports: [LazyModule] // Eager load }) export class AppModule { }
// Fix 3: Use forRoot pattern @NgModule({ providers: [LazyService] }) export class LazyModule { static forRoot(): ModuleWithProviders { return { ngModule: LazyModule, providers: [LazyService] }; } }
// Import with forRoot @NgModule({ imports: [LazyModule.forRoot()] }) export class AppModule { } ```
Step 8: Fix @Inject Decorator Issues
```typescript // Wrong injection token type export const CONFIG = 'config'; // String, not InjectionToken
constructor(@Inject(CONFIG) private config: any) { }
// This may work but is not type-safe
// Better: Use InjectionToken export const CONFIG = new InjectionToken<AppConfig>('config');
interface AppConfig { apiUrl: string; timeout: number; }
constructor(@Inject(CONFIG) private config: AppConfig) { }
// Provide with correct type @NgModule({ providers: [ { provide: CONFIG, useValue: { apiUrl: 'https://api.example.com', timeout: 30000 } } ] }) export class AppModule { } ```
Step 9: Use providedIn Syntax
```typescript // Modern Angular (v6+) prefers providedIn // Old approach (module providers) @NgModule({ providers: [MyService] }) export class MyModule { }
// New approach (tree-shakeable) @Injectable({ providedIn: 'root' }) export class MyService { }
// Benefits: // - Tree-shakeable (removed if not used) // - No module registration needed // - Singleton by default
// For non-root scope @Injectable({ providedIn: 'any' // New instance in each lazy module }) export class ScopedService { } ```
Step 10: Debug with Injector Tree
```typescript // Visualize injector hierarchy // In component: constructor(private injector: Injector) { // Walk up injector tree let current = this.injector; while (current) { console.log('Injector:', current); current = current.parent; } }
// Check if provider exists constructor(private injector: Injector) { try { const service = this.injector.get(DataService); console.log('DataService found:', service); } catch (e) { console.log('DataService NOT found in this injector'); } }
// Use Angular DevTools // Shows component tree and injector hierarchy // chrome://extensions -> Angular DevTools ```
Provider Configuration Patterns
| Pattern | Use Case | Scope |
|---|---|---|
| providedIn: 'root' | App-wide singleton | Entire app |
| providedIn: Module | Feature-scoped | That module only |
| providedIn: 'any' | Separate per lazy module | Each lazy module |
| Module providers | Module-specific | Module + imports |
| Component providers | Component-local | That component only |
Verification
```typescript // After fixing provider configuration
// 1. Run application ng serve
// Should start without NullInjectorError
// 2. Test service injection // In component: constructor(private dataService: DataService) { console.log('DataService:', this.dataService); }
// Should log the service instance, not error
// 3. Check module imports // Verify all required modules imported @NgModule({ imports: [ HttpClientModule, FeatureModule, // All modules providing needed services ] }) export class AppModule { }
// 4. Build for production ng build --prod
// Should succeed without injection errors
// 5. Check in Angular DevTools // Open DevTools, check injector tree // Verify services appear in correct injector ```
Prevention
To prevent Angular dependency injection errors from recurring, implement these proactive measures:
1. Use providedIn for Services
```typescript // Preferred approach - tree-shakeable @Injectable({ providedIn: 'root' // Singleton across app }) export class UserService { }
// For feature-scoped services @Injectable({ providedIn: 'any' // New instance per lazy module }) export class FeatureService { } ```
2. Enable Strict Injection Parameters
```json // tsconfig.json { "angularCompilerOptions": { "strictInjectionParameters": true, "strictTemplates": true } }
// Catches injection errors at compile time ```
3. Document Provider Scope
/**
* UserService - Manages user authentication and profile
* @providedIn root - Singleton service available app-wide
* @requires HttpClient - Must import HttpClientModule
*/
@Injectable({ providedIn: 'root' })
export class UserService {
constructor(private http: HttpClient) {}
}Best Practices Checklist
- [ ] Use providedIn for services
- [ ] Enable strict injection parameters
- [ ] Document provider scope
- [ ] Use Angular CLI for service generation
- [ ] Test service injection in unit tests
- [ ] Review provider configuration
Related Issues
- [Fix Angular Change Detection Loop](/articles/fix-angular-change-detection-loop)
- [Fix Angular Module Not Found](/articles/fix-angular-module-not-found)
- [Fix Angular Ivy Compilation Failed](/articles/fix-angular-ivy-compilation-failed)
Related Articles
- [Technical troubleshooting: Fix Browser Back Button State Lost Spa Navigation ](browser-back-button-state-lost-spa-navigation)
- [Fix Cors Fetch Localhost Development Blocked Issue in Frontend](cors-fetch-localhost-development-blocked)
- [Fix Csp Violation Blocked Inline Script Style Issue in Frontend](csp-violation-blocked-inline-script-style)
- [Fix Angular Change Detection Loop](fix-angular-change-detection-loop)
- [Fix Angular ExpressionChangedAfterItHasBeenCheckedError](fix-angular-expressionchangedafterchecked)
<script type="application/ld+json"> { "@context": "https://schema.org", "@type": "TechArticle", "headline": "Fix Angular Dependency Injection Error", "description": "Troubleshoot Angular dependency injection errors. Check provider configuration, module imports, and injection tokens.", "url": "https://www.fixwikihub.com/fix-angular-dependency-injection-error", "publisher": { "@type": "Organization", "name": "FixWikiHub", "url": "https://www.fixwikihub.com" }, "author": { "@type": "Person", "name": "FixWikiHub Editorial Team" }, "datePublished": "2026-04-04T03:12:02.747Z", "dateModified": "2026-04-04T03:12:02.747Z" } </script>