5

Im looking for a way to use one angular route resolve to use on all of my routes, but with different parameters:

currently, i have something like:

   {
        path: 'user/:any',
        component: UserprofileComponent,
        resolve: { ProfiledUser: UserprofileResolver }
      },

profileuser resolve:

 resolve(route: ActivatedRouteSnapshot) {
    return this.GlobalService.Get('/userprofile/admin');
  }

Im in fact looking for a way to use the parameters the Get function from GlobalService is using, for the resolver itself.

I have made something previously that could in theory work:

  path: 'family/panel',
        component: FamilyCoreComponent,
        canActivate: [PermissionGuardService],
        data: {roles: [0]},

where canactivate permission guard:

  canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot):Observable<boolean>|boolean {

    var requirementRole = next.data.roles[0];

So my question is, should i use the principle for the resolver, as i did to my permission guard?

For example something like:

  {
    path: 'user/:any',
    component: UserprofileComponent,
    resolve: { ProfiledUser: UserprofileResolver }
    data: {load: 'userprofile/admin'},
  },

Would this be a good way to do it? if so, how would i do it to make this the most efficient?

1
  • Check this Medium article which as a pretty good example of how to use a resolver and how to reuse the component as subcomponent as well: medium.com/@santibarbat/… Commented May 9, 2020 at 12:13

1 Answer 1

1
+50

great question, made me scratch my head for quite some time too :).

So let's dive in my solution for this problem.

When using Resolver we have the ability to replace the resolver with anything we like (functions/classes).

@NgModule({
  imports: [
    RouterModule.forRoot([
      {
        path: 'team/:id',
        component: TeamComponent,
        resolve: {
          team: 'teamResolver'
        }
      }
    ])
  ],
  providers: [
    {
      provide: 'teamResolver',
      useValue: (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => 'team'
    }
  ]
})

This snippet comes straight from the ng Docs

So in your case, you are able some extra parameters in the useValue line, like this

useValue: (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) =>
  new ResolverWithParamsResolver(
          route,
          state,
          "customLink"
      ).resolve()

And your ResolverWithParamsResolver you might have, something like the following code snippet

export interface ResolverWithParamModel<T> {
  resolve(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot,
    linkParam: string
  ): Observable<T> | Promise<T> | T;
}
// Custom resolver
@Injectable()
export class ResolverWithParamsResolver implements ResolverWithParamModel<any> {
  constructor(
    private route: ActivatedRouteSnapshot,
    private state: RouterStateSnapshot,
    private linkParam: string
  ) {}

  resolve(): Observable<any> | Promise<any> | any {
    return of(this.linkParam)
  }
}

So now you will have access to your linkParam.

Here is a demo, which is a bit more complex than the snippets in the answer, that implements the desired effect.

Note:

If I have 10 to 15 possible different configurations for the custom resolver, I would probably create 10-15 resolvers, as it will be easier to understand from the first glance what does each resolver do.

Disclaimer:

Not sure if this is the best solution, but I think something along these lines is the thing that you desire, if you meet any trouble with the implementation, please create a stackblitz/codesandbox/plunker demo and I will do my best to help you :)

Sign up to request clarification or add additional context in comments.

3 Comments

Same idea, it's at best to create multiple resolver. Verbose and easy to understand, also if there is one route/module get a major refactoring, you will change the resolver for that specific area only.
I'm not sure if thats fully cover what OP was asking for. I am actually missing one key point here - how to use subsequent resolved values in TeamComponent. I tried to subscribe to "activatedRoute.data" yet for after navigating to other route and back, the subscription no longer provides values. Probably this is separate question - I'll continue to look for other questions and possibly write my own.
well actually I just found out having proper routing set up the activatedRoute.data emits newly resolved values as it should (possibly via advanceActivatedRoute from router-state.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.