Revoir le live Angular du 16 octobre

Anticipez le futur avec Signal Forms d'Angular

Angular 21 introduira Signal Forms, une nouvelle API expérimentale qui simplifiera radicalement la gestion des formulaires.

Basée sur les signaux, elle permettra :

  • de créer des formulaires déclaratifs avec form()
  • de lier directement les champs avec [field]
  • d'intégrer facilement les validations et la soumission
  • et de réduire le boilerplate tout en améliorant les performances
Skip to content

Vous souhaitez recevoir de l'aide sur ce sujet ? rejoignez la communauté Angular.fr sur Discord.

Important (contexte)

les Signal Forms sont encore expérimentaux et liés à la future version Angular 21 (docs "next"), donc l'API peut encore bouger. Utilisez-les en connaissance de cause et suivez les notes de version.


Les formulaires « orientés signaux » arriveront avec Angular 21 (16 octobre 2025)

Les Signal Forms projettent le système de signals d'Angular au cœur des formulaires : chaque champ, chaque état (valide, en erreur, pending…), devient un signal. Résultat : une UI qui réagit dès qu'une valeur ou une erreur change, sans abonnements manuels. Cette API vit (pour l'instant) dans la doc next et est marquée experimental since v21.0.

Revoir le live


Pourquoi c'est intéressant

  • Moins de boilerplate : on décrit quoi valider plutôt que comment écouter.
  • Réactivité native : les champs exposent des signals (valeur, erreurs, validité, submitting, pending, etc.).
  • Typage fort : la forme du formulaire épouse votre modèle TS.
  • Migration progressive : peut cohabiter avec les formulaires réactifs classiques.

Qu'est-ce que les formulaires orientés signaux ?

Imaginez que vous remplissez un formulaire d'inscription sur un site web. Traditionnellement, Angular vérifiait les erreurs de validation de manière périodique, comme un contrôleur qui passe dans une salle de classe pour vérifier les copies. Avec les signaux, c'est comme avoir un assistant personnel qui vous prévient immédiatement dès qu'une erreur apparaît ou disparaît, en temps réel !

Les formulaires orientés signaux transforment les formulaires Angular en entités entièrement réactives, où chaque changement de valeur, chaque erreur de validation, et chaque état du formulaire sont des signaux que vous pouvez écouter et réagir instantanément.

Pourquoi cette révolution ?

Les problèmes des formulaires traditionnels

Avant Angular 21, gérer les formulaires nécessitait souvent beaucoup de code boilerplate et des vérifications manuelles de l'état des formulaires. Vous deviez :

  • Créer des FormControl, FormGroup manuellement
  • Gérer manuellement les validations
  • Écouter les changements avec des observables complexes
  • Synchroniser l'état entre le formulaire et vos composants

Les avantages des signaux

Les formulaires orientés signaux apportent :

  • Réactivité automatique : Plus besoin de souscrire manuellement aux changements
  • Syntaxe simplifiée : Moins de code boilerplate
  • Performance optimisée : Seules les parties qui changent sont recalculées
  • Intégration native : Parfaitement intégrés avec l'écosystème des signaux

Étape 1 — Première approche (le « Hello form »)

Objectif : lier deux inputs à un modèle, avec une validation minimale.

Idées clés

  • On déclare un signal de données (le modèle).
  • On crée le formulaire avec form(model, (p) => { … }).
  • On relie les <input> avec la directive [field] (à exposer en important la directive Field).
  • On enregistre les validateurs déclaratifs (required, minLength, email, …). Ces helpers sont marqués experimental since v21.0.

Ce que vous verrez dans le code

  • import { Field, form, required, email } from '@angular/forms/signals'
  • Dans le template : <input [field]="userForm.email">

Pourquoi [field] ? Parce que l'API expérimentale définit un sélecteur de directive qui relie un champ de formulaire à un contrôle UI ; la structure d'état exposée s'appuie sur FieldState (valeur, erreurs, valid, pending, submitting, etc.).


typescript
import { Component, computed, effect, signal } from '@angular/core';
import { FormControl } from '@angular/forms';
import { Field, FieldPath, form, min, minLength, required, submit } from '@angular/forms/signals';

function groupValidator(path: FieldPath<{
  firstName: string
}>) {
  required(path.firstName)
  minLength(path.firstName, 3)
}

@Component({
  selector: 'app-root',
  templateUrl: './app.html',
  styles: `
    .green {
      color: green;
    }
  `,
  imports: [Field]
})
export class App {
  profile = signal({
    firstName: '',
    email: ''
  })
  profileForm = form(this.profile, (path) => {
    groupValidator(path)
  })
  isFirstNameValid = computed(() => this.profileForm.firstName().valid())
  nbErrors = computed(() => this.profileForm.firstName().errors().length)

  constructor() {
    effect(() => {
      console.log(this.profileForm().value())
    })
  }

  editProfile(event: Event) {
    event.preventDefault()
    submit(this.profileForm, async (form) => {
      console.log(form().value())
    })
  }
}
html
<form (submit)="editProfile($event)" novalidate>
  <label>Prénom</label>
  <input type="text" [field]="profileForm.firstName">
  <p [class.green]="isFirstNameValid()">Test</p>

  @if (nbErrors() != 0) {
    <p>Il y a des erreurs</p>
  }

  <button>Modifier</button>
</form>

Étape 2 — Aller un peu plus loin (messages d'erreur, état global)

Objectif : afficher des erreurs lisibles et désactiver le bouton Submit tant que le formulaire est invalide.

Points d'attention

  • field().errors() renvoie un tableau d'objets d'erreur (pas un objet "dot-access"). Pour tester une erreur précise, parcourez le tableau et vérifiez error.kind ('required', 'minLength', 'email', …).
  • L'état global du formulaire se lit via le champ racine : userForm().valid, userForm().value(), userForm().submitting, etc. (tous exposés comme signals).

Ce que vous verrez dans le code

  • Un @for sur userForm.firstName().errors() ?? [] pour afficher des messages.
  • Un bouton <button [disabled]="!userForm().valid">…</button>.

Étape 3 — Approche « avancée » (soumission asynchrone & erreurs serveur)

Objectif : effectuer une soumission asynchrone (HTTP) en utilisant l'utilitaire submit(…) et refléter l'état (submitting) côté UI.

Idées clés

  • submit(form, async action) valide, gèle les champs le temps de l'action, expose submitting, puis répercute le résultat.
  • Vous pouvez mapper des erreurs serveur sur des champs (ex. "email déjà utilisé") et les afficher exactement comme des erreurs locales.
  • Côté template, utilisez userForm().submitting pour un spinner ou pour désactiver les actions. Les propriétés de FieldState documentent ces états.

Comparaison rapide (mental model)

  • Formulaires réactifs classiques : pilotés par FormGroup/FormControl + Observables (valueChanges).
  • Signal Forms : on déclare la logique de validation à la création, puis on réagit via des signals partout dans l'UI (pas d'abonnements manuels). Des retours de la communauté soulignent ce changement de modèle et l'intérêt pour la lisibilité / dynamiques conditionnelles. (Reddit)

Bonnes pratiques & pièges courants

  • Tapez votre modèle (évitez any) : le field tree (userForm.firstName) tire son type de votre interface.
  • Nommez la directive correctement : c'est [field] (pas [formControlName], ni [control]). (De nombreux billets parlent de proto/variantes ; fiez-vous aux docs next.)
  • Erreurs : souvenez-vous que errors()array d'objets { kind, message? }. Ne faites pas errors?.required.

FAQ express

Q. Est-ce que c'est prêt pour la prod ? R. À l'heure où j'écris, c'est expérimental et documenté sur le site "next" : prudence, tests, et surveillez les releases.

Q. Est-ce que ça remplace les Reactive Forms ? R. Pas tout de suite. Pensez "nouvelle option" centrée signals. Les deux approches coexisteront un moment.

Q. Où trouver la doc officielle ? R. Les pages next décrivent les types et propriétés de l'API (FieldState, validateurs required, etc.).