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:

typescript
ERROR NullInjectorError: No provider for DataService!
    at NullInjector.get (core.js:824)
    at R3Injector.get (core.js:891)

Provider not found:

bash
ERROR Error: Uncaught (in promise): NullInjectorError: No provider for HttpClient!
NullInjectorError: No provider for HttpClient!

Injection token error:

typescript
ERROR NullInjectorError: No provider for InjectionToken API_CONFIG!

Circular dependency:

bash
ERROR Error: Cannot instantiate cyclic dependency! (ComponentA -> ComponentB -> ComponentA)

Common Causes

  1. 1.Missing provider - Service not registered in any module
  2. 2.Module import missing - HttpClientModule not imported
  3. 3.Wrong provider scope - Service in wrong module (root vs feature)
  4. 4.InjectionToken not provided - Token missing providedIn
  5. 5.Circular dependency - Services depend on each other
  6. 6.Lazy module isolation - Service in lazy module not accessible
  7. 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

PatternUse CaseScope
providedIn: 'root'App-wide singletonEntire app
providedIn: ModuleFeature-scopedThat module only
providedIn: 'any'Separate per lazy moduleEach lazy module
Module providersModule-specificModule + imports
Component providersComponent-localThat 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

typescript
/**
 * 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
  • [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)
  • [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>