Search code examples
angularroutesangular-routingangular-router

Angular Route: call service method from routes array config


I would like to call a method of a service (AuthService.getRequiredGroup) within the routes array, inside my AppRoutingModule.

I can't figure out if it's possible to do it and how

My code

import { AuthService } from './shared/services/auth.service';

const routes: Routes = [
  {
    path: '',
    component: LoginComponent,
    data: {
      breadcrumb: 'Login',
      hidden: true
    }
  },
  {
    path: 'projects',
    canActivate: [AuthGuard],
    children: [
      {
        path: '',
        component: ProjectsListComponent,
        canActivate: [AuthGuard`your text`],
        data: {
         requiredGroup: AuthService.getRequiredGroup("prj_list")// will return["ruolo1","superadmin"]
          
         }
      },
  }
]


@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule],
  providers: [AuthService]
})
export class AppRoutingModule {
  constructor(
    @Inject(APP_CONFIG) public config: any
  ) { }
}

I would like to be able to call a method of a service within AppRoutingModule


Solution

  • You can certainly use the ResolveFn which automatically runs when the user goes into a specific route. For this, you should have a function in your service class as your data provider. Then you can call that function through resolveFn from your route. The result of the data provider function will be available in all components that are inside that route. One cool thing about this approach is that your components won't load until the resolver has finished fetching data. So, you can call multiple API requests using resolver and your component will work once all of them have finished executing and you have everything in your component. Here is a simple example:

    Steps:

    1. Write the data provider function in your service class.

    export class HeroService {
          getHero(id: string) {
            return {myid: id};
          }
        }

    1. Write your resolver function that injects the data provider function into your route. You can also pass route parameters from the route into your data provider function.

    export const heroResolver: ResolveFn < Hero > =
      (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => {
        return inject(HeroService).getHero(route.paramMap.get('id') !);
      };

    1. In your route file, call the resolver like this. If you are passing id or any other route data, you can pass it to the resolve as well.

    bootstrapApplication(App, {
      providers: [provideRouter([{
        path: 'detail/:id',
        component: HeroDetailComponent,
        resolve: {hero: heroResolver},
      }])]
    });

    1. Now is the fun part! You can access the data that your data provider function returned in your component. Please note that the component has to be defined in the same route path block, or it has to be a child component of that route path block. Otherwise, it won't work. You can access the data in the ngOnInit function of your component.

    export class HeroDetailComponent {
      constructor(private activatedRoute: ActivatedRoute) {}
    
      ngOnInit() {
        this.activatedRoute.data.subscribe(
          ({
            hero
          }) => {
            // do something with your resolved data ...
          });
      }
    }

    Here is the documentation if you need more information: https://angular.io/api/router/ResolveFn