Skip to content

injectParams

Created by Enea Jahollari

injectParams is a helper function that allows us to inject params from the current route as a signal.

Having params as a signal helps in a modern angular signals based architecture.

import { injectParams } from 'ngxtension/inject-params';

injectParams returns a signal with the current route params.

@Component({
standalone: true,
template: '<div>{{params() | json}}</div>',
})
class TestComponent {
params = injectParams();
}

Or, if we want to transform the params, we can pass a function to injectParams.

@Component()
class TestComponent {
paramsKeys = injectParams((params) => Object.keys(params)); // returns a signal with the keys of the params
}

If we want to get the value for a specific param, we can pass the name of the param to injectParams.

@Component({
template: `
@if (user(); as user) {
<div>{{ user.name }}</div>
} @else {
<div>No user!</div>
}
`,
})
class TestComponent {
userId = injectParams('id'); // returns a signal with the value of the id param
user = derivedFrom(
[this.userId],
switchMap((id) => this.userService.getUser(id).pipe(startWith(null))),
);
}

If you want to parse the specific param, you can pass a parse function.

@Component({
template: `
@if (user(); as user) {
<div>{{ user.name }}</div>
} @else {
<div>No user!</div>
}
`,
})
class TestComponent {
userId = injectParams('id', { parse: numberAttribute }); // returns a signal with the value of the id param parsed to a number
user = derivedFrom(
[this.userId],
switchMap((id) => this.userService.getUser(id).pipe(startWith(null))),
);
}

If we want to use a default value if there is no value, we can pass a defaultValue.

@Component({
template: `
@if (angular(); as angular) {
<div>{{ angular.name }}</div>
} @else {
<div>No Angular version found!</div>
}
`,
})
class TestComponent {
angularVersion = injectParams('version', { defaultValue: '19' }); // returns a signal with the value of the version param or '19' if not present
angular = derivedFrom(
[this.angularVersion],
switchMap((version) =>
this.angularService.getAngular(version).pipe(startWith(null)),
),
);
}

injectParams.global() allows you to access route params from the entire route hierarchy, including all parent and child routes. This is similar to Angular’s input() and input.required() pattern.

@Component()
class ParentComponent {
// Gets all params from parent and all child routes
// Child params override parent params if they have the same name
allParams = injectParams.global();
}
@Component()
class ParentComponent {
// Gets the 'id' param from anywhere in the route hierarchy
id = injectParams.global('id');
}
@Component()
class ParentComponent {
// Transform all params from the route hierarchy
paramCount = injectParams.global((params) => Object.keys(params).length);
}

All the same options work with .global():

@Component()
class TestComponent {
// Parse param as number
userId = injectParams.global('id', {
parse: numberAttribute,
});
}

A common use case is building breadcrumbs that need access to all route params:

@Component({
template: `
<nav>
@for (crumb of breadcrumbs(); track crumb.path) {
<a [routerLink]="crumb.path">{{ crumb.label }}</a>
}
</nav>
<router-outlet />
`,
})
class LayoutComponent {
allParams = injectParams.global();
// Build breadcrumbs using all params from route hierarchy
breadcrumbs = computed(() => buildBreadcrumbs(this.allParams()));
}