Skip to main content

Command Palette

Search for a command to run...

formArray.patchValue(...) : attention à son utilisation !

Updated
3 min read
formArray.patchValue(...) : attention à son utilisation !
E

Je suis Ezéchiel Amen AGBLA, Angular Developer Expert & Ionic Developer Expert, passionné par le développement web et mobile. Je mets la lumière sur des notions liées à Angular et à Ionic pour la communauté francophone.

Si vous avez l’habitude de manipuler des formulaires réactifs (Reactive Forms) dans un projet Angular, vous connaissez certainement la méthode patchValue(…). Cette méthode, permet de mettre à jour les valeurs de votre formulaire. Cependant, son utilisation sur un formulaire ayant un contrôle de type FormArray qui n’est rien d’autre qu’un formulaire dynamique, dans lequel vous pouvez ajouter et supprimer des contrôles au moment de l'exécution est très délicate. Dans cet article, nous verrons ensemble, pourquoi faut t-il faire attention à la façon dont nous utilisons patchValue(…) lorsqu’il s’agit d’un formulaire ayant un contrôle de type FormArray.

Avant d’entrer dans le vif du sujet, nous rappellerons, l’utilisation classique de la méthode patchValue(…) sur un formulaire simple. Considérons, le bout de code suivant où nous avons un composant ProfileEditorComponent dans lequel est implémenté un formulaire simple composé de deux champs à savoir firstName et lastName :

import {Component} from '@angular/core';
import {FormGroup, FormControl} from '@angular/forms';

@Component({
  selector: 'app-profile-editor',
  templateUrl: './profile-editor.component.html',
  styleUrls: ['./profile-editor.component.css'],
  standalone: true,
})

export class ProfileEditorComponent {
  profileForm = new FormGroup({
    firstName: new FormControl(''),
    lastName: new FormControl('')
  });
}

Dans l’exemple susmentionné, pour mettre à jour les valeurs de notre formulaire en utilisant patchValue(…), voici ce que nous faisons :

this.profileForm.patchValue({
    firstName: 'John',
    lastName: 'Doe'
});

Une fois, ce bout de code exécuté, notre formulaire sera mis à jour avec les valeurs John pour le firstName et Doe pour le lastName.

La question qui vient à l’esprit est la suivante ?

Est-ce aussi le cas lorsque nous faisons face à un formulaire qui contient des contrôles de type FormArray ?

La meilleure façon de s’en assurer, est de faire l’expérience. Let’s go !

Considérons le code ci-dessous :

import { Component } from '@angular/core';
import { FormBuilder, FormArray, FormGroup } from '@angular/forms';

@Component({
  selector: 'app-addresses',
  template: `
    <form [formGroup]="addressesForm">
      <div formArrayName="addresses">
        <div *ngFor="let address of addresses.controls; let i = index" [formGroupName]="i">
          <input type="text" formControlName="road" placeholder="Road">
          <input type="text" formControlName="city" placeholder="City">
        </div>
        <button type="button" (click)="addAddress()">Add an address</button>
      </div>
    </form>
  `
})
export class AddressesComponent {
  addressesForm = new FormGroup({
   addresses: new FormArray([
      new FormGroup({
        road: new FormControl(),
        city: new FormControl()
      })
   ])
 });

  public get addressesFormArray() {
    return this.addressForm.get('addresses');
 }
}

Dans le code ci-dessus, nous avons un formulaire qui contient un contrôle de type FormArray. Supposons, qu’après un traitement, nous voulons mettre à jour les adresses de notre formulaire en utilisant naturellement notre méthode patchValue(…). Voici ce que nous écrirons :

this.addressesFormArray.patchValue([
    {
        road: '1',
        city: 'Paris'
    },
    {
        road: '2',
        city: 'Lyon'
    },
    {
        road: '3',
        city: 'Marseille'
    }
]);

Dans notre exemple, si l’on se confère à la logique de la méthode patchValue(…), normalement, notre formulaire doit être mis à jour avec les valeurs des adresses indiquées.

Malheureusement, je ne suis navré de vous décevoir mais ce n’est pas le cas !

Lorsqu’on se rend sur l’interface web, on se rend compte que c’est uniquement le premier objet du tableau des adresses qui est conservé comme valeur.

Notre méthode patchValue(…) n’a pas su itérer sur le reste des éléments et c’est là tout le piège !

Pour résoudre ce problème, une gymnastique s’impose à nous lors de l’utilisation de notre méthode patchValue(…). Voici donc comment procéder étape par étape :

Étape 1 : Nettoyer notre FormArray

this.addressesFormArray.clear();

Étape 2 : Recréer une nouvelle instance de notre FormArray

/*
    Considérons une variable `myAddresses` qui contient toutes les adresses récupérées 
    après un appel d'API par exemple
*/

while (this.addressesFormArray.controls.length < myAddresses.length) {
   this.addressesFormArray.push(new FormGroup({
        road: new FormControl(),
        city: new FormControl()
    }));
}

Étape 3 : Mettre à jour les valeurs avec patchValue(…)

this.addressesFormArray.patchValue(myAddresses);

En somme, pour appliquer un patchValue(…) sur notre formulaire, il est crucial d’identifier la nature des contrôles. S’agit t-il d’un FormControl classique ou d’un FormArray conduisant à un formulaire complexe ? Suivant, le cas, nous savons aujourd’hui quoi faire.

Pour plus d'informations 👉 Reactive Forms

More from this blog

A

angulardev.fr

25 posts

Je suis Ezéchiel Amen AGBLA, Angular Developer Expert & Ionic Developer Expert, passionné par le développement web et mobile.