Reputation: 6579
i have the following Component Structure
So my routing looks like this:
const childroutes = [
{
path: '',
children: [
{ path: 'edit', component: EditProjectComponent},
{ path: 'subres1', component: Subres1Component},
{ path: 'subres2', component: Subres2Component},
{ path: 'subres3', component: Subres3Component},
{ path: 'subres4', component: Subres4Component}
]
}
]
{
path: 'project/:projectId',
component: ProjectDetailComponent,
children: childroutes,
resolve: { project: ProjectResolver} /** resolve Project from ProjectService **/
}
As you can see i resolve my Projectdata from a service and can access them in ProjectDetailComponent via
this.route.snapshot.data
So now the question is, how can i pass the data resolved in "EditProjectComponent" to all its childroutes components?
I now that i could do the following to resolve project-data in childcomponents:
const childroutes = [
{
path: '',
children: [
{ path: 'edit', component: EditProjectComponent,resolve: { project: ProjectResolver}},
{ path: 'subres1', component: Subres1Component,resolve: { project: ProjectResolver}},
{ path: 'subres2', component: Subres2Component,resolve: { project: ProjectResolver}},
{ path: 'subres3', component: Subres3Component,resolve: { project: ProjectResolver}},
{ path: 'subres4', component: Subres4Component,resolve: { project: ProjectResolver}}
]
}
]
But this seems ugly and wrong.
Upvotes: 33
Views: 23645
Reputation: 1621
Quite late response, but I think it's worth pointing this out: If routes change the parent reference might not work anymore. For a more flexible and resilient architecture you could use a service which would store the resolved data.
Resolver
@Injectable({ providedIn: 'root' })
export class ProjectResolver implements Resolve<Project> {
constructor(
private service: ProjectService,
private store: StoreService,
) {}
resolve(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Observable<Hero>|Promise<Hero>|Hero {
return this.service.getProject(route.paramMap.get('id'))
.pipe(tap(project => this.store.project = project));
}
}
Then you can access this data anywhere you need it:
const projects = this.store.project;
Of course the store solution could be just a simple service with a class variable for projects, or something as complex as ngrx/store library.
Note: In case you don't find it proper to modify the state from the resolver code using something like tap, you could alter the state from the component that has that resolver, and access the state from the children components, or anywhere in the app where that data is needed.
Upvotes: 0
Reputation: 316
You just need to do this in child components:
ngOnInit() {
this.route.parent.data
.subscribe((data) => {
this.edit = data.edit;
});
}
Upvotes: 6
Reputation: 1552
You have two options here:
1. You can access parent resolve data via the child's resolver by creating a child-specific resolver and accessing the route's parent property.
[...module.ts | ...component.ts]
{
path: 'project/:projectId',
component: ProjectDetailComponent,
resolve: { project: ProjectResolver }
children: [
{
path: ':projectId/edit',
component: EditProjectComponent,
resolve: { edit: EditProjectResolve }
}
]
}
edit-project-component.ts
ngOnInit() {
this.edit = this.route.snapshot.data.edit;
}
2. You can bypass the child's resolver all together and access parent data from within the child component.
[...module.ts | ...component.ts]
{
path: 'project/:projectId',
component: ProjectDetailComponent,
resolve: { project: ProjectResolver }
children: [
{
path: ':projectId/edit',
component: EditProjectComponent
}
]
}
edit-project-component.ts
ngOnInit() {
this.route.parent.data
.subscribe((data) => {
this.edit = data.edit;
});
}
Upvotes: 54