Flyii
Flyii

Reputation: 1155

How to define enums as route parameters

i am trying to set up my router so that it takes routes with ../RouteSegment1/RouteSegment2/...

enum RouteSegment1 {
  value1,
  value2
}

enum RouteSegment2 {
  value1,
  value2
}

A working solution would be to define every route explicitly like this

const routes: Routes = [
  {
    path: '', component: ParentComponent, children: [
      {
        path: RouteSegment1.value1,
        component: RouteSegment1Component,
      },
      {
        path: RouteSegment1.value2,
        component: RouteSegment1Component,
      },
      {
        path: RouteSegment1.value1/RouteSegment2.value1,
        component: RouteSegment2Component,
      },
      {
        path: RouteSegment1.value1/RouteSegment2.value2,
        component: RouteSegment2Component,
      },
      {
        path: RouteSegment1.value2/RouteSegment2.value1,
        component: RouteSegment2Component,
      },
      {
        path: RouteSegment1.value2/RouteSegment2.value2,
        component: RouteSegment2Component,
      },
    ]
  },
];

As you can see this is definely not a good solution and would get worse later down the line.

My ultimate goal is to set up my routes like this:

const routes: Routes = [
  {
    path: '', component: ParentComponent, children: [
      {
        path: RouteSegment1,
        component: RouteSegment1Component,
      },
      {
        path: RouteSegment1/RouteSegment2,
        component: RouteSegment2Component,
      },
    ]
  },
];

Therefore routes that are not a value of the enums would not route to the RouteSegmentComponents and i would have a scalable solution.

Maybe there is a way to use route parameters by limiting the possible values to the enum. Unfortunately i was not able to come up with a working solution. I tried to use guards on those segments to check if the parameter was a valid value of the enum. Maybe i was just implementing those wrong.

Was that the right approach? How can i configure my Routes to be scalable with the given SegmentEnums?

Upvotes: 1

Views: 6529

Answers (2)

Flyii
Flyii

Reputation: 1155

So i made a second attempt to my first approach and i managed to get it working.

I defined my SegmentEnums

enum RouteSegment1 {
  value1,
  value2
}

enum RouteSegment2 {
  value1,
  value2
}

Created a Guard

export class EnumRouteGuard implements CanActivate {

  constructor(private router: Router) { }

  public canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
    const segment1: string = next.paramMap.get('routeSegment1')!;
    const segment2: string = next.paramMap.get('routeSegment2')!;

    const segment1IsEnum = Object.keys(RouteSegment1).find(key => RouteSegment1[key] === segment1);
    const segment2IsEnum = Object.keys(RouteSegment2).find(key => RouteSegment2[key] === segment2);

    if (!(segment1IsEnum && segment2IsEnum) ) {
      this.router.navigate([someOtherRoute]);
      return false;
    }
    return true;
  }
}

And used them in my Routes

const routes: Routes = [
  {
    path: '', component: ParentComponent, children: [
      {
        path: ':routeSegment1',
        component: RouteSegment1Component,
         canActivate: [EnumRouteGuard],
      },
      {
        path: ':routeSegment1/:routeSegment2',
        component: RouteSegment2Component,
        canActivate: [EnumRouteGuard],
      },
    ],
  },
];

Upvotes: 1

user10933473
user10933473

Reputation:

It is no clear what you are going to achieve.

At least, Your code

{
   path: RouteSegment1.value1/RouteSegment2.value1,
   component: RouteSegment2Component,
},

should be written as

{
    path: RouteSegment1.value1,
    component: RouteSegment1Component,
    children: [
      {
        path: RouteSegment2.value1,
        component: RouteSegment2Component
      }
    ]
  }

Upvotes: 0

Related Questions