Executing resolvers one after the other in Angular 2+
One other option is to wrap your dependent routes and use necessary resolver on wrapper.
I.E.
{ path: '', resolve: { foo$: FooResolver }, children: [
{ path: 'mySubRoute', resolve: {bar$: BarResolver }, component: BarComponent }
]}
*If you meet with relative path resolving problems, try using
relativeLinkResolution: "corrected"
In forRoot router method. More info here Angular RouterLink relative path does not work in component having empty path
I found a slightly more elegant solution that can be used if you don't care about the results from all of the resolvers:
class FooBarResolver implements Resolve<Observable<any>> {
constructor(
protected fooResolver: FooResolver,
protected barResolver: BarResolver
) { }
resolve(): Observable<any>
{
return this.fooResolver.resolve().pipe(
concat(this.barResolver.resolve()),
concat(this.barResolver.resolve())
);
}
}
I use this to trigger the data loading in my services. And because they write the data / isLoading / error into an Akita storage, I don't care about the results of the resolvers.
Resolvers are resolved in parallel. If Foo
and Bar
are supposed to be resolved in series they should be a single FooBar
resolver. If they are supposed to be used by themselves in other routes, FooBar
can wrap Foo
and Bar
resolvers:
class FooBarResolver implements Resolve<{ foo: any, bar: any }> {
constructor(
protected fooResolver: FooResolver,
protected barResolver: BarResolver
) {}
async resolve(route): Promise<{ foo: any, bar: any }> {
const foo = await this.fooResolver.resolve(route);
const bar = await this.barResolver.resolve(route);
return { foo, bar };
}
}
FooBar
should be aware of the fact if it is a promise or an observable that is returned from Foo
and Bar
in order to resolve them properly. Otherwise additional safety device should be added, like await Observable.from(this.fooResolver.resolve(route)).toPromise()
.
FooBar
and Foo
or Bar
shouldn't appear within same route because this will result in duplicate resolutions.