~3 min de lecture
Et si withComponentInputBinding était plus structurant qu’on ne le croit ?
withComponentInputBinding() est un petit helper arrivé avec Angular v16 (puis amélioré en v17+), mais qui peut avoir *
un impact sur certains de vos choix*.
🧩 Le problème avant
Avant, pour récupérer les paramètres de route dans un composant, même en full Signals, il fallait passer par
ActivatedRoute et toSignal :
@Component({
standalone: true,
template: `Profil de {{ userId() }}`
})
export default class ProfilPage {
private route = inject(ActivatedRoute);
readonly userId = toSignal(
this.route.paramMap.pipe(map(params => params.get('userId') ?? 'anonyme'))
);
}
Même avec Signals, on reste dépendant de RxJS + boilerplate + complexité.
✅ Ce qu’apporte withComponentInputBinding
Pour activer cette fonctionnalité, il faut ajouter withComponentInputBinding() dans la configuration du routeur
global :
bootstrapApplication(App, {
providers: [
provideRouter(routes, withComponentInputBinding())
]
});
Et dans le fichier de routes :
import { Routes } from '@angular/router';
export const routes: Routes = [
{ path: 'profil/:userId', loadComponent: () => import('./profil.page') }
];
Puis, dans le composant :
@Component({
standalone: true,
template: `Profil de {{ userId() }}`
})
export default class ProfilPage {
readonly userId = input<string>();
}
➡️ Le paramètre :userId est automatiquement injecté dans l’input userId.
➡️ Plus besoin d’injecter ActivatedRoute, ni de transformer quoi que ce soit.
➡️ Valable avec les routes params, queryParams, data et resolver.
➡️ Nos composants vont donc être plus facilement réutilisables puisque plus directement liés à l'ActivatedRoute.
🧠 Comparaison AVANT / APRÈS
| Aspect | Avant | Après |
|---|---|---|
| Lecture des params | ActivatedRoute + toSignal() |
input() |
| Boilerplate | élevé | minimal |
| Dépendances | RxJS, ActivatedRoute | Angular Signals uniquement |
| Tests | plus difficiles | plus simples (inputs injectables) |
| Clarté de lecture | moyenne | excellente |
⚠️ Un comportement à connaître : valeurs par défaut ignorées
Un piège assez subtil existe :
Si la route n’injecte aucune valeur dans un input défini avec input('valeurParDefaut'), la valeur par défaut est *
ignorée*.
Exemple :
@Component({
standalone: true,
template: `Profil de {{ userId() }}`
})
export default class ProfilPage {
readonly userId = input('anonyme');
}
Mais si la route ne définit pas :userId, le composant reçoit… undefined.
Pourquoi ? Parce qu’Angular assigne explicitement
undefinedà tout input lié, mais non présent dans la route, ce qui écrase la valeur par défaut.
Ce comportement a été discuté dans une issue GitHub où j’ai proposé une amélioration pour conserver les valeurs par défaut quand aucun paramètre n’est fourni.
Cela a été refusé, mais le comportement sera précisé dans la documentation.
🛠 Contournement
Valeur par défaut dans la route
Pour éviter ce comportement, il faut toujours fournir une valeur dans la configuration de la route, par exemple :
export const routes: Routes = [
{
path: 'profil',
// injecté dans l'input
data: { userId: 'anonyme' },
loadComponent: () => import('./profil.page'),
}]
computed / linkedSignal
Ou bien gérer l’input côté composant :
export class ProfilPage {
readonly userId = input<string | undefined>();
readonly safeUserId = computed(() => this.userId() ?? 'anonyme');
}
Input transform
Ou encore utiliser la fonction de transformation de notre input :
export class ProfilPage {
readonly userId = input<string | undefined, string>(undefined, {
transform: (value) => (value === undefined ? '2' : value),
});
}
🧱 Conclusion
withComponentInputBinding()rend vos composants plus concis.- Il s’intègre parfaitement avec les Signals.
- Et il faut être attentif aux valeurs non fournies, sous peine d’écraser les valeurs par défaut.
- Peut-être vaut-il mieux ne pas avoir d'input par défaut (seulement des required) dans nos composants de routing.
- Ou alors toujours considérer que la valeur peut être
undefined.
Tu veux aller plus loin sur le Routing Angular, en pratique ?
➡️ Découvre le Module 5 d’EasyAngularKit – Maîtriser le routing (v19)