Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Form control valueChanges gives the previous value

I have a form control with name 'question1' within the form object parentForm and I have subscribed to it in the following way.

Its a radio button with two options Yes and No, when I select No I get Yes and when I select Yes its a 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 variable has the correct value but if I do console.log(this.parentForm.value['question1'] it gives the previous value.

I tried to put a setTimeout() before retrieving value from this.parentForm.value['question1'], It just works fine.

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

But my question is why parentForm is not updated when its control's value changes and that too I am retrieving its value only after value was changed.

Note: I don't want to observe for parentForm.valueChanges, not my requirement.

like image 461
Amit Chigadani Avatar asked Jul 04 '17 06:07

Amit Chigadani


People also ask

What is the purpose of the ValueChanges method on a FormControl?

The ValueChanges is an event raised by the Angular forms whenever the value of the FormControl, FormGroup or FormArray changes. It returns an observable so that you can subscribe to it. The observable gets the latest value of the control. It allows us to track changes made to the value in real-time and respond to it.

How do you find the value of the form controls?

Get and Set Value To fetch the value of a form control, we have to use value property on the instance of FormControl in our class. In the same way we can fetch the value in HTML template. city = new FormControl('Noida'); console.

What is the function of form control?

Form controls enable accessibility by taking a uniform approach to such features as captions, help text, tabbing and keyboard shortcuts. Internationalization issues are addressed by following the same design principles as in XHTML. All form controls are suitable for styling using Aural CSS (ACSS) style properties.


1 Answers

valueChanges is an Observable so you can pipe pairwise to get the previous and next values in the subscription.

// 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]) => ... ); 

Example of it working in StackBlitz: https://stackblitz.com/edit/angular-reactive-forms-vhtxua

Update

If you're noticing that startWith appears to be deprecated this is not the case. There is only a single active signature for the operator, which you can read about in this answer.

Highly likely, you are using startWith(null) or startWith(undefined), they are not deprecated despite the notice, but IDE detects a wrong function signature, which is deprecated, and shows the warning.

A simple work around is providing the return type that would be expected:

// Prevent deprecation notice when using `startWith` since it has not been deprecated this.form.get('fieldName')   .valueChanges   .pipe(startWith(null as string), pairwise())   .subscribe(([prev, next]: [any, any]) => ... ); 

Example of it working in StackBlitz with startWith: https://stackblitz.com/edit/angular-reactive-forms-rvxiua

like image 169
mtpultz Avatar answered Sep 21 '22 02:09

mtpultz