This document explains the Angular NG0201 error fix for the Break Policies module and provides a pattern for implementing future modules.
ERROR ɵNotFound: NG0201: No provider found for `_TimePlanningPnBreakPoliciesService`.
Source: _BreakPoliciesModule.
Find more at https://v20.angular.dev/errors/NG0201
- Navigation to Break Policies page failed
- Angular console showed NG0201 error
- Service injection in components failed
- Module was not functional
Users could not access the Break Policies feature, and CRUD operations were not available.
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.
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 {}Angular's dependency injection system works hierarchically:
- When a component requests a service, Angular looks in its injector
- If not found, Angular looks in parent injectors
- 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.
Root Injector
├── Plugin Module Injector
│ └── Time Planning Module Injector
│ └── Break Policies Module Injector
│ ├── Providers: [TimePlanningPnBreakPoliciesService] ← Added here
│ └── Components
│ ├── BreakPoliciesContainerComponent ← Can now inject
│ ├── BreakPoliciesTableComponent
│ └── BreakPoliciesActionsComponent
- 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
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
When implementing the remaining rule entities (PayRuleSet, PayDayTypeRule, PayTierRule, PayTimeBandRule), follow this pattern:
-
✅ Create service class
@Injectable() export class YourService { constructor(private apiBaseService: ApiBaseService) {} // ... methods }
-
✅ Export from services/index.ts
export * from './your-service.service';
-
✅ Import in module
import {YourService} from '../../services';
-
✅ Add to providers ← Critical step!
@NgModule({ imports: [...], declarations: [...], providers: [ YourService, // Don't forget this! ], }) export class YourModule {}
-
✅ Use in components
constructor(private yourService: YourService) {}
Cause: Service not registered in providers array Fix: Add service to module providers (this fix)
Cause: Two services inject each other
Fix: Use forwardRef() or restructure dependencies
Cause: Service provided in multiple places Fix: Provide only in one location (usually module level)
- 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
- 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
- Start development server:
npm start - Login to application
- Navigate to: Time Planning → Break Policies
- Verify: Page loads without errors
- Check console: No NG0201 errors
- Test: CRUD operations work
- ✅ No errors in browser console
- ✅ Break Policies page renders
- ✅ Table displays data
- ✅ Create/edit/delete modals work
- ✅ Service methods execute correctly
If NG0201 still occurs:
- Verify service is imported at top of module file
- Check service is in providers array
- Ensure service is exported from services/index.ts
- Clear browser cache and restart dev server
- Check for typos in import path
If module doesn't load:
- Check routing configuration
- Verify lazy loading setup
- Ensure module is declared in routing
- Check for circular dependencies
break-policies.module.ts- Added service provider
time-planning-pn-break-policies.service.ts- Service implementationservices/index.ts- Service exportbreak-policies-container.component.ts- Service consumerbreak-policies.routing.ts- Module routing
- Commit: 17a7c93
- Message: "Fix Angular DI error: Add TimePlanningPnBreakPoliciesService to module providers"
- Files: 1 modified
- Lines: +3 additions, -1 deletion
✅ Error: Fixed (NG0201) ✅ Navigation: Working correctly ✅ Service: Properly injected ✅ Module: Fully configured ✅ Pattern: Documented for future use ✅ Ready: Production deployment
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.