08 May 2023
5 min

Router data as components inputs in Angular v16

Up until now, we have considered properties decorated with @Input as properties bound to the DOM properties. These properties can be used to pass data from parent to child. For instance, if a child component has an input property called name, we can use it like this:

<app-child name="John"></app-child>

Starting from Angular version 16, we can use inputs to declare properties that will bind to route parameters.

What does this mean? Let's consider the following route definition:

const routes: Routes = [
  {
    path: 'hero/:id',
    component: ChildComponent,
  },
];

When we need to obtain the ID in our component, such as when fetching a hero using its ID, we would do the following in the component:

export class ChildComponent {
  constructor(route: ActivatedRoute) {
    route.params.subscribe((params) => console.log(params.id));
  } 
}

Now we can use @Input for that. It's as simple as that.

export class ChildComponent {
  @Input() id: string;
}

That’s not all! We can access variety of route parameters, including:

  • route parameters
  • query parameters
  • route data from data property
  • route data from resolvers

Let's quickly check the rest, starting from this route definition:

const routes: Routes = [
  {
    path: 'hero/:id',
    component: ChildComponent,
    resolve: {
      heroName: () => 'Yoda',
    },
    data: {
      heroPower: 'Force',
    },
  },
];

We have

  • id as route parameter
  • heroName as data from resolver
  • heroPower as data from data property

In the component, we can add input properties for all of these, as well as an additional one for a query parameter, as follows:

export class ChildComponent {
  @Input() id?: string;
  @Input() heroName?: string;
  @Input() heroPower?: string;
  @Input() heroParameter?: string;
}

That's it! Everything works automatically, and input properties pick up the current route parameters without the need for injecting ActivatedRoute into the component anymore.

Have fun and enjoy Angular 16 features! ?

Frequently asked questions

How do I get route parameters as inputs in Angular 16?

In Angular 16 and later, declare an @Input() property with the same name as the route parameter, such as @Input() id?: string; for the path hero/:id. The input receives the current value automatically, so you don't need to inject ActivatedRoute or subscribe to route.params.

Do I still need ActivatedRoute to read route parameters in Angular 16?

Not for the values covered here: since Angular 16, @Input() properties receive route parameters directly, so you no longer need to inject ActivatedRoute to read an ID like id. Before Angular 16, the same value required constructor injection and a route.params.subscribe() call, which added boilerplate to the component.

Can I bind query parameters to component inputs in Angular?

Yes. Query parameters can be received the same way: declare an @Input() property whose name matches the query parameter key, such as @Input() heroParameter?: string;. It sits alongside route parameter inputs like id in the same component class. Use optional typing (?) because the value may be absent from the URL.

How do I pass resolver data and route data to component inputs in Angular?

Yes. Values from a route's resolve object, such as heroName returned by a resolver, and values from its data property, such as heroPower, are both bound to @Input() properties with matching names. For example, @Input() heroName?: string; and @Input() heroPower?: string; need no ActivatedRoute injection. Declare each property with the exact key from the route configuration.

Share this post

Sign up for our newsletter

Stay up-to-date with the trends and be a part of a thriving community.