How to Pass Url Query Parameters (Routing Params) to Input() Decorator with Transform in Angular

Erman Enginler
HAVELSAN
Published in
3 min readNov 10, 2023

In this article we are going to learn how to pass router query parameters to an Input() decorator in a component easily. Then we transform query type to a specific type that we need.

Created with Adobe Firefly

At the time I wrote this article I use:
node v16.20.0
npm v8.19.4
angular@16.2.0

Think that you need to get URL query (assume it is “id”) and use it in your code. Before Angular 16 you have to inject ActivatedRoute to your code and use this activatedRoute to get paramMap of the router snapshot.

//getting url param with ActivatedRoute before Angular 16 (pseudocode)

import { ActivatedRoute } from '@angular/router'; //import package from module
...
...
constructor(private activatedRoute: ActivatedRoute){} //dependency injection
...
...
ngOnInit():void{
const id = this.route.snapshot.paramMap.get('id'); //get from route snapshot
}
...
...

After the release of Angular 16 we now have ability to get route parameters directly to Input() variables.

But how do we do that?

First, we need to pass withComponentInputBinding() as argument to provideRouter() method in ApplicationConfig.

// app.config.ts
import { provideRouter, withComponentInputBinding } from '@angular/router';
....
....
export const appConfig: ApplicationConfig = {
providers: [
provideHttpClient(),
provideRouter(routes, withComponentInputBinding())
]
...
};

If you are still using ngModules add { bindToComponentInputs: true } in RouterModule.forRoot([...]) See more details in here

Now it is time to use query (routing) params in a component.

Assume we have a routing like this.

export const routes: Routes = [
...
{
path: "item/:id",
component: ItemComponent
}
...
];

To get the id from the URL http://localhost:4200/item/5 we only get id from Input() thanks to withComponentInputBinding.

export class ItemComponent implements OnInit {

@Input() id!:string;

ngOnInit(){
console.info("id:",this.id);
}
}

With this approach you may both use id from nested data transfers (data binding) and from routing query.

That’s all for getting the param. Now think that you have to send this parameter to a service. Like maybe you want to use it as a parameter to a request. As you know requests have specific interfaces so maybe you may want to change the type of the query (default: string).

After the release of Angular 16.1.0 there comes an option for Input() decorator to transform the value to a specific type.

Most useful ones are booleanAttribute and numberAttribute.

Let’s see how numberAttribute work.

In this case we get id from query and post request to a service with param id as number.

import { numberAttribute } from '@angular/core';
....
....
export class ItemComponent implements OnInit {

@Input({transform:numberAttribute}) id!:number;

protected postDetailUrl: string = `https://jsonplaceholder.typicode.com/posts`;
item!:Item;

constructor(private http:HttpClient){}

private getPostDetail(id:number): Observable<Item> {
return this.http.get<Item[]>(
this.postDetailUrl,
{params:{id}}
).pipe(
map((items:Item[]) => items[0] )
);
}

ngOnInit(){
this.getPostDetail(this.id).subscribe((res:Item)=>{
this.item = res;
})
}
}

As we can see in the code above, we use {transform:numberAttribute} in Input() decorator to transform string param to number. Then we post to a service using this param as number.

That’s all. Please like.

You may download the sample project on GitHub
ermaneng/medium_query_input (github.com)

Good readings
ermaneng

--

--