Skip to content

Latest commit

 

History

History
245 lines (186 loc) · 6.89 KB

File metadata and controls

245 lines (186 loc) · 6.89 KB

Angular Dependency Injection Fix

Overview

This document explains the Angular NG0201 error fix for the Break Policies module and provides a pattern for implementing future modules.

Error

ERROR ɵNotFound: NG0201: No provider found for `_TimePlanningPnBreakPoliciesService`. 
Source: _BreakPoliciesModule.
Find more at https://v20.angular.dev/errors/NG0201

Problem Description

Symptoms

  • Navigation to Break Policies page failed
  • Angular console showed NG0201 error
  • Service injection in components failed
  • Module was not functional

Impact

Users could not access the Break Policies feature, and CRUD operations were not available.

Root Cause

The BreakPoliciesModule had an empty providers array:

@NgModule({
  imports: [...],
  declarations: [...],
  providers: [],  // ← Empty = no services available
})
export class BreakPoliciesModule {}

When BreakPoliciesContainerComponent tried to inject the service:

constructor(private breakPoliciesService: TimePlanningPnBreakPoliciesService) {}

Angular's dependency injection system couldn't find a provider for the service, resulting in the NG0201 error.

Solution

Code Changes

File: eform-client/src/app/plugins/modules/time-planning-pn/modules/break-policies/break-policies.module.ts

Step 1: Import the service

import {TimePlanningPnBreakPoliciesService} from '../../services';

Step 2: Add to providers array

@NgModule({
  imports: [...],
  declarations: [...],
  providers: [
    TimePlanningPnBreakPoliciesService,  // ← Service now available
  ],
})
export class BreakPoliciesModule {}

Why This Works

Angular's dependency injection system works hierarchically:

  1. When a component requests a service, Angular looks in its injector
  2. If not found, Angular looks in parent injectors
  3. If no provider is found anywhere, NG0201 error is thrown

By adding the service to the module's providers array, we register it with the module's injector, making it available to all components in that module.

Technical Details

Angular DI Hierarchy

Root Injector
├── Plugin Module Injector
│   └── Time Planning Module Injector
│       └── Break Policies Module Injector
│           ├── Providers: [TimePlanningPnBreakPoliciesService]  ← Added here
│           └── Components
│               ├── BreakPoliciesContainerComponent  ← Can now inject
│               ├── BreakPoliciesTableComponent
│               └── BreakPoliciesActionsComponent

Service Scope

  • Singleton: One instance per module
  • Lazy-loaded: Service created only when module loads
  • Isolated: Service not accessible outside module unless provided elsewhere
  • Injectable: Available to all components within the module

Lazy Loading

The Break Policies module is lazy-loaded, meaning:

  • Module code is loaded only when user navigates to it
  • Module creates its own injector
  • Services must be provided in the module's providers
  • Services are not available until module loads

Pattern for Future Modules

When implementing the remaining rule entities (PayRuleSet, PayDayTypeRule, PayTierRule, PayTimeBandRule), follow this pattern:

Step-by-Step Checklist

  1. Create service class

    @Injectable()
    export class YourService {
      constructor(private apiBaseService: ApiBaseService) {}
      // ... methods
    }
  2. Export from services/index.ts

    export * from './your-service.service';
  3. Import in module

    import {YourService} from '../../services';
  4. Add to providers ← Critical step!

    @NgModule({
      imports: [...],
      declarations: [...],
      providers: [
        YourService,  // Don't forget this!
      ],
    })
    export class YourModule {}
  5. Use in components

    constructor(private yourService: YourService) {}

Common Angular DI Errors

NG0201: No provider found

Cause: Service not registered in providers array Fix: Add service to module providers (this fix)

NG0203: Circular dependency detected

Cause: Two services inject each other Fix: Use forwardRef() or restructure dependencies

NG0200: Multiple providers for same token

Cause: Service provided in multiple places Fix: Provide only in one location (usually module level)

Best Practices

✅ DO

  • Always add services to module providers
  • Import services from the services barrel (../../services)
  • Keep services scoped to modules for lazy loading
  • Follow established patterns in the codebase
  • Test navigation immediately after creating module

❌ DON'T

  • Leave providers array empty when using services
  • Provide services in both root and module
  • Skip import statements
  • Mix service registration patterns
  • Assume services are globally available

Verification

How to Test

  1. Start development server: npm start
  2. Login to application
  3. Navigate to: Time Planning → Break Policies
  4. Verify: Page loads without errors
  5. Check console: No NG0201 errors
  6. Test: CRUD operations work

Expected Behavior

  • ✅ No errors in browser console
  • ✅ Break Policies page renders
  • ✅ Table displays data
  • ✅ Create/edit/delete modals work
  • ✅ Service methods execute correctly

Troubleshooting

If NG0201 still occurs:

  1. Verify service is imported at top of module file
  2. Check service is in providers array
  3. Ensure service is exported from services/index.ts
  4. Clear browser cache and restart dev server
  5. Check for typos in import path

If module doesn't load:

  1. Check routing configuration
  2. Verify lazy loading setup
  3. Ensure module is declared in routing
  4. Check for circular dependencies

Related Files

Modified

  • break-policies.module.ts - Added service provider

Related (unchanged)

  • time-planning-pn-break-policies.service.ts - Service implementation
  • services/index.ts - Service export
  • break-policies-container.component.ts - Service consumer
  • break-policies.routing.ts - Module routing

Commit Reference

  • Commit: 17a7c93
  • Message: "Fix Angular DI error: Add TimePlanningPnBreakPoliciesService to module providers"
  • Files: 1 modified
  • Lines: +3 additions, -1 deletion

Status

Error: Fixed (NG0201) ✅ Navigation: Working correctly ✅ Service: Properly injected ✅ Module: Fully configured ✅ Pattern: Documented for future use ✅ Ready: Production deployment

Conclusion

This was a straightforward Angular configuration issue. The service existed and was exported, but wasn't registered in the module's providers array. Adding the service to providers resolved the NG0201 error and made the Break Policies module fully functional.

This pattern must be followed for all future lazy-loaded modules to ensure proper dependency injection.