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

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` :

```typescript
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 :

```typescript
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 :

```typescript
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 :

```typescript
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`

```typescript
this.addressesFormArray.clear();
```

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

```typescript
/*
    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(…)`

```typescript
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](https://angular.dev/guide/forms/reactive-forms)
