web-dev-qa-db-fra.com

Formulaire valeur de contrôleChanges donne la valeur précédente

J'ai un contrôle de formulaire avec le nom 'question1' Dans l'objet de formulaire parentForm et je m'y suis abonné de la manière suivante.

C'est un bouton radio avec deux options Yes et No, lorsque je sélectionne No, je reçois Yes et lorsque je sélectionne Yes c'est un No.

this.parentForm.controls['question1'].valueChanges.subscribe(
  (selectedValue) => {
    // If option `No is selected`
    console.log(selectedValue);  // displays No. OK
    console.log(this.parentForm.value['question1']);  // displays Yes. Problem is here
  }
);

selectedValue la variable a la valeur correcte mais si je le fais console.log(this.parentForm.value['question1'], elle donne la valeur précédente.

J'ai essayé de mettre une setTimeout() avant de récupérer la valeur de this.parentForm.value['question1'], Cela fonctionne parfaitement.

setTimeout(() => {
  console.log(this.parentForm.value['question1']); // gives the correct value.
}, 500);

Mais ma question est de savoir pourquoi parentForm n'est pas mis à jour lorsque la valeur de son contrôle change et que, lui aussi, je récupère sa valeur uniquement après que la valeur a été modifiée.

Note: Je ne veux pas observer pour parentForm.valueChanges, Pas mon exigence.

25
Amit Chigadani

valueChanges est un observable afin que vous puissiez diriger pairwise pour obtenir les valeurs précédente et suivante de l'abonnement.

// No initial value. Will emit only after second character entered
this.form.get('fieldName')
  .valueChanges
  .pipe(pairwise())
  .subscribe(([prev, next]: [any, any]) => ... );
// Fill buffer with initial value, and it will emit immediately on value change
this.form.get('fieldName')
  .valueChanges
  .pipe(startWith(null), pairwise())
  .subscribe(([prev, next]: [any, any]) => ... );

Exemple d'utilisation de StackBlitz: https://stackblitz.com/edit/angular-reactive-forms-vhtxua

32
mtpultz

L'événement valueChanges est déclenché après la nouvelle valeur est mise à jour avec la valeur FormControl et avant la modification est renvoyée à son parent et ancêtres. Par conséquent, vous devrez accéder à la valeur de FormControl elle-même (qui vient d'être corrigée), pas à un champ de l'objet FormGroup value (non modifié pendant l'événement).

À la lumière de cela, utilisez this.parentForm.get('question1').value à la place:

this.parentForm.controls['question1'].valueChanges.subscribe(
    (selectedValue) => {
      console.log(selectedValue);
      console.log(this.parentForm.get('question1').value);     
    }
);
26
Harry Ninh

Il existe une option supplémentaire, mais elle peut ne pas convenir dans tous les cas: vous pouvez attendre ne coche avant le selectedValue est mis à jour dans FormControl:

setTimeout( () => console.log( selectedValue ) );

Pour en savoir plus sur les formulaires sync/async: Formulaires réactifs in Angular Guide docs.

3
nesinervink

Essayez de faire ça

this.parentForm.controls['question1'].valueChanges.subscribe(
    (selectedValue) => {
      console.log(selectedValue);
      console.log(this.parentForm.value.question1);     
    }
);

si les contrôles de FormBuilder ont été mis à jour, vous pouvez immédiatement récupérer les dernières valeurs de l'objet FormBuilder via la valeur de la propriété