javascriptangulartypescriptangular-aot

How to make Route data typed in Angular 7 (in production)?


import { environment } from '@env/environment';

export const routes: Routes = [
  {
    path: '',
    children: [
      {
        path: 'organisations',
        component: OrganisationListComponent,
        data: {
          [environment.router.data.resourceName]: 'ORGANISATION' // <- error
        }
      },
      {
        path: 'organisations/create',
        component: OrganisationCreateComponent,
        data: {
          [environment.router.data.resourceName]: 'ORGANISATION_LIST' // <- error
        },...
      }

This is part of one of my routing module files. As you can see I want route data to have a property whose name I defined in environment file. But this won't work when compiling with --aot flag. This is the error:

ERROR in Error during template compile of 'AdminRoutingModule'
  Expression form not supported in 'routes'
    'routes' contains the error at app/admin/admin-routing.module.ts(30,11).

I have around 30 routes in my application, and all of them have data property with the key 'resourceName'. And I don't want to repeat this string 30 times in my application.

I cannot create class which has resourceName property and instantiate it inside data, because function expressions aren't allowed inside route configuration either.

Is there a way around this, or it's simply not possible to achieve with AOT complier?

Edit: this is environement.ts file:

export const environment = {
  production: true,
  version: '1.0.0',
  router: {
    data: {
      resourceName: 'resourceName'
    }
  }
}

Solution

  • Declare your own Route data type. Extend from @angular/router's Route so it's all type-safe. This way, it's possible to assert the existence of the resourceName property, which could even be omitted otherwise.

    No need to involve the environment module in the process.

    import { RouterModule, Route } from '@angular/router';
    
    export interface MyRoute extends Route {
        data: {
            resourceName: string;
        };
    }
    
    export declare type MyRoutes = MyRoute[];
    
    export const routes: MyRoutes = [
      {
        path: '',
        children: [
          {
            path: 'organisations',
            component: OrganisationListComponent,
            data: {
              resourceName: 'ORGANISATION'
            }
          },
          {
            path: 'organisations/create',
            component: OrganisationCreateComponent,
            data: {
              resourceName: 'ORGANISATION_LIST'
            },...
          }