0

I'm trying to implement a functional canActivate guard in Angular v16, but I'm facing an issue with retrieving dynamic route parameters. I want to access the username and id parameters from the route in my guard function, but when I try to retrieve them using route.snapshot.paramMap.get('paramName'), they always return null. Here's an example of my guard function:

typescript

export const postGuard = () => {
  const route = inject(ActivatedRoute);
  const username = route.snapshot.paramMap.get('username') as string;
  const id = route.snapshot.paramMap.get('id') as string;
  console.log(username); // Always null
  return true;
};

I have already injected the ActivatedRoute in my guard function, but the username and id parameters are not being populated correctly. The console.log(username) statement always shows null.

Is there any other way to retrieve the dynamic route parameters in a functional canActivate guard without using ActivatedRoute in Angular v16? I would greatly appreciate any insights or examples demonstrating the correct approach to achieve this. Thank you!

syahiruddin
  • 401
  • 5
  • 14

2 Answers2

1

I found this article from Angular documentation helpful.

I figured out how to get the dynamic parameters by using CanActivateFn as a type and passing in ActivatedRouteSnapshot & RouterStateSnapshot as a parameter. Now I can just call the route and get the dynamic param.

export const postGuard: CanActivateFn = (
  route: ActivatedRouteSnapshot,
  state: RouterStateSnapshot
) => {
  // get dynamic route params
  const id = route.paramMap.get('id') as string;
  const username = route.paramMap.get('username') as string;
  console.log('id: ', id);
  console.log('username: ', username);

  return true;
};
syahiruddin
  • 401
  • 5
  • 14
0

In Angular 16 + There are much good solution but first you need to import in Route File.

@NgModule({
  imports: [RouterModule.forRoot([], { bindToComponentInputs: true })],
})

Then we can use in various ways like

const routes: Routes = [
  {
    path: "search/:id",
    component: SearchComponent,
    data: { title: "Search" },
    resolve: { searchData: SearchDataResolver }
  },
];


@Component({})
export class SearchComponent {
    @Input() query?: string; // this will come from the query params
    @Input() id?: string; // this will come from the path params
    @Input() title?: string; // this will come from the data
    @Input() searchData?: any; // this will come from the resolved data 

}

No Ng init or something else. Any kind of additional data can directly use in @Input.

Angular 16 Release Note https://blog.angular.io/angular-v16-is-here-4d7a28ec680dCheck check Passing router data as component inputs

https://itnext.io/bind-route-info-to-component-inputs-new-router-feature-1d747e559dc4 Original article On this feature

Puneet Sharma
  • 307
  • 3
  • 9