Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
2.4k views
in Technique[技术] by (71.8m points)

angular - 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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...