FrancescoDonzello
Angular Share on Twitter

New in Angular v16: Route Param to Component inputs

4 minutes read
#articles#angular

One of the new features introduced by Angular 16 is the ability to bind route parameters directly to component inputs. This addition improves the component’s isolation and makes them more reusable. This blog post aims to provide a step-by-step guide on how to enable and utilize this innovative feature.

Traditional way of retrieving route params

Let’s say we have the following routes configuration:

app.routes.ts
export const routes: Routes = [
  {
      path: 'news',
      loadComponent: () => import('./news/news.component'),
      children: [
          {
              path: ':id',
              loadComponent: () => import('./news/news-detail.component'),
          },
      ]
  },
];

For years we’ve been using the ActivatedRoute service to retrieve route params like the id of the News Detail route. And it’s been working pretty well so far.

However, this approach has a few drawbacks:

news-detail.component.ts
export default class NewsDetailComponent implements OnInit {
  private readonly route = inject(ActivatedRoute);
 
  ngOnInit(): void {
    this.route.paramMap.subscribe(params => {
      const id = params.get('id');
    })
  }
}

New way of retrieving route params

With Angular 16, instead, we can remove all the boilerplate code and simply bind route params to component inputs.

In the following sections, we explore how to enable this feature both on a standard Angular application using modules and on a complete module-less app.

Enable with Standalone Components

Just pass withComponentInputBinding() to the provideRouter() function.

app.config.ts
export const appConfig: ApplicationConfig = {
  providers: [
    provideRouter(routes, withComponentInputBinding())
  ]
};

Enable with Module

The RouterModule.forRoot static method accepts an object as the second argument to enable features.

Make sure to set bindToComponentInputs to true to bind route params to component inputs.

app-routing.module.ts
@NgModule({
  imports: [
    RouterModule.forRoot(routes, { bindToComponentInputs: true })
  ],
  exports: [RouterModule]
})
export class AppRoutingModule { }

Let’s bind params!

Now that we’ve enabled the feature, the id property will be automatically bound to the id route param.

news-detail.component.ts
export default class NewsDetailComponent {
  @Input() id!: string;
}

React on param changes

With the paramMap observable we were able to react to param changes but we lost this ability when switching to the new approach.

To react on param changes, you can use the setter of the id property. This setter is called every time the id route param changes.

In the example below, I reassigned the news$ observable every time the id changes. An async pipe in the template is used to subscribe to the observable and render the data.

news-detail.component.ts
export default class NewsDetailComponent {
  news$?: Observable<News>;
 
  _news = inject(NewsService);
 
  @Input() set id(id: string) {
    this.news$ = this._news.getById(id);
  }
}

Route Data are supported too

Router bindings are not limited to route params.

If you have data set at the route level, you can bind that as well and no extra configuration is required.

Considerations

The new Angular 16 feature that binds route parameters and data directly to component inputs promotes better component isolation, and simplifies testing by minimizing dependencies on services like ActivatedRoute.

This is again an effort from the Angular team to make the framework less verbose and more intuitive.

← Back to Angular Articles

Was it helpful?

Tell your friends or co-workers.