Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create a angular resolver for multiple usage

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?

like image 337
maria Avatar asked Nov 06 '22 19:11

maria


1 Answers

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 :)

like image 63
Християн Христов Avatar answered Nov 13 '22 16:11

Християн Христов