I have a lazy loaded module with all it components declared and routes added in RouterModule.forChild()
but some of these routes have their resolver that will prefetch some data And call a service to change something in the parent component header like the following:
//Imports...
@Injectable({
providedIn: 'root',
})
export class MyVendorHeaderResolver implements Resolve<Header> {
constructor(private vendorHeaderService: VendorHeaderService) {}
resolve(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Observable<Header> {
const title: string = 'MainNav.NavMenu.Vendors.Action.MyVendor';
const breadcrumbs: Breadcrumb[] = [
{ displayText: 'MainNav.NavMenu.Vendors.Title', link: '..' },
{
displayText: 'MainNav.NavMenu.Vendors.Action.MyVendor',
link: route.routeConfig.path,
},
];
//this change the header of the main page component if
this.vendorHeaderService.changeHeader({ title, breadcrumbs } as Header);
// if the pervious line works with the same instance of the service provided in module,
// i'd not need to return anything form this resolver
return of({ title, breadcrumbs } as Header);
}
}
so this VendorHeaderService
:
//imports
@Injectable({
providedIn: 'root',
})
export class VendorHeaderService {
private header$ = new Subject<Header>();
constructor() {}
headerChange(): Subject<Header> {
return this.header$;
}
changeHeader(header: Header) {
this.header$.next(header);
}
}
this is the routing module:
const routes: Routes = [
{
path: '',
redirectTo: 'vendors/vendors-categories',
pathMatch: 'full',
},
{
path: 'vendors',
component: VendorsComponent,
children: [
{
path: 'vendors-categories',
component: VendorsCategoriesComponent,
canActivate: [VendorsCategoriesGuard],
resolve: {
header: VendorCategoryHeaderResolver,
categories: VendorsCategoriesResolver,
},
children: [
{
path: 'new',
component: VendorCategoryDialogEntryComponent,
},
{
path: ':vendorCategoryId',
component: VendorCategoryDialogEntryComponent,
canActivate: [VendorCategoryGuard],
resolve: {
categoryDialogData:
VendorCategoryDialogInfoResolver,
},
},
],
},
],
},
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class VendorsAndCustomersRoutingModule {}
I want it to be provided only in my Lazy Loaded Module but I can't cause it used in the resolver.
so my question:
Is it possible to make the resolver service instance is the same one of that used in the module components without exposing the service outside with this provideIn: 'root'
?
I've made the services all provided in the 'root' Enviroment Injector and it's working fine, but the service is exposed to any place in the app
if i understand your problem... in the module where you want to use the service, you can use the providers array in the module metadata like this:
the service will become a singletone within the context of the module. in your resolver you can use the @skipSelf injection operator to skip inject the service from resolver and listen to it through the injection hierarchy -which is injected from the module - like this:
, so in this way, you use the same service instance in the resolver and any component in the module.