I need to pass providers to a Lazy loaded module. Context: I have a module that access an API and returns some configs to be rendered in the components. This is the Module:
@NgModule({
declarations: [AuxTablesComponent, AuxTablesListingComponent],
providers: [AuxTablesService, AuxTableDataResolverGuard],
imports: [CommonModule, AuxTablesRoutingModule, SharedModule]
})
export class AuxTablesModule {}
Imported as Lazy on another module:
const routes: Routes = [
{
path: AIRPORTS_ROUTES.AUX_TABLES.route,
loadChildren: () => import('./aux-tables/aux-tables.module').then(m => m.AuxTablesModule)
}
...
]
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class AirportsRoutingModule {}
This works as a charm. But now I need the same exactly Module, with the same views and behaviour in another Module, but I need to change the providers responsible for fetching the data from another API. So I would like to change the AuxTablesService and AuxTableDataResolverGuard.
I was trying to something like this: Importing it into another module, in this case the TrainsModule
const routes: Routes = [
{
path: TRAINS.AUX_TABLES.route,
loadChildren: () => import('./aux-tables/aux-tables.module').then(m => m.AuxTablesModule
.forChild(newApiProvider, newResolverGuard))
}
...
]
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class TrainsRoutingModule {}
And prepare the AuxTablesModule to receive custom providers like this:
@NgModule({
declarations: [AuxTablesComponent, AuxTablesListingComponent],
providers: [AuxTablesService, AuxTableDataResolverGuard],
imports: [CommonModule, AuxTablesRoutingModule, SharedModule]
})
export class AuxTablesModule {
static forChild(auxTableApiService: AuxTablesService, auxTableGuardResolver: Resolve<IAuxTable>) {
return {
ngModule: AuxTablesModule,
providers: [
{
provide: AuxTablesService,
useClass: auxTableApiService
},
{
provide: AuxTablesService,
useClass: auxTableGuardResolver
}
]
};
}
}
But when angular tries to render the forChild lazy module, i get this error:
core.js:6014 ERROR Error: Uncaught (in promise): Error: No NgModule metadata found for '[object Object]'.
Debbuing angular, the return Object is not a contructor and cannot be "factoried" as a module nor finding the meta data as @ngModule on it. Does, anyone knows how to such a thing? Like provide custom classes to lazy loaded modules?
Well, I got a workaround but doesn't seem right. I remove the providers from the module I want to lazy load.
It got like this:
Then I passed the providers to each module that is lazy importing it:
and:
So, the lazy loaded module looks for the providers on it self, but it can't find. So it looks for its parent module, and find it, so it can be instanced with its parent injecting the providers.
But I really would like to have my module with its own providers, and be overwritten when lazy loaded.