4

I'm learning to use Reactive Forms in Angular 6, so forgive me if this question is stupid, but here's my issue:

I want to monitor for changes of a certain value in my reactive form, because when a change occurs I need to run some logic that recalculates stuff based on the new values. So I've tried doing this:

this.inputGroup = formBuilder.group({
  myControl: 'something'
});

this.inputGroup.get('myControl').valueChanges.subscribe(newVal => {
  console.log("new value", newVal); //Prints the correct new value
  console.log("actual value", this.inputGroup.value.myControl); //Prints the previous (old) value!

  this.someFuncThatExpectsTheValuesToBeUpToDate(); //This will find the OLD value inside this.inputGroup.value.myControl, instead of the new one!
});

but, as you can see from the comments I put in the code, this doesn't work because valueChanges seems to get called before the value is actually changed in the model! Is this intended behavior? The method signature for valueChanges says:

A multicasting observable that emits an event every time the value of the control changes, in the UI or programmatically.

so I would have assumed that it was called AFTER the value was changed in the form, but apparently not... is this correct? And if so, how can I detect when the value has actually changed in the control?

EDIT: there seems to be some confusion (as always here on SO :D) about WHY I want my function to access the data directly from the Form group, instead of passing the new value to the function itself. This is easily explained: the function gathers data from several form groups and uses this data to do some side-calculations. By accessing the data directly from the form groups, the function is generic and can be invoked from anywhere. If I start to put input parameters there, this would break. Take this example:

someFuncThatExpectsTheValuesToBeUpToDate(){
  let val1 = inputGroup.value.myControl;
  let val2 = someOtherFormGroup.value.myOtherControl;
  let val3 = yetAnotherFormGroup.value.someOtherControl;
  //do something with the vals
}

With this function, I can invoke it from anywhere and it will work. But if I need to pass in the values each time, I would need 3 different functions with different signatures to do the same thing, much more messy and complicated.

10
  • Are you saying your finction "someFuncThatExpectsTheValuesToBeUpToDate" is not getting updated value? Commented Oct 16, 2018 at 14:07
  • @DheerajKumar: exactly, basically when valueChanges fires the underlying value in the controls is not updated yet, it still holds the old value. Commented Oct 16, 2018 at 14:09
  • Don't you think you need to pass the changed value to your function? Since out of subscriber, it will be out of scope. Commented Oct 16, 2018 at 14:10
  • console.log("actual value", inputGroup.value.myControl); What is inputGroup here anyway? And what are you trying to accomplish? Why don't you just pass newVal to your method which needs it? Commented Oct 16, 2018 at 14:17
  • @DheerajKumar: Yes, I could pass the new value as a workaround, but I would prefer if the function obtains the values directly from the current model. This makes the function more generic and I can invoke it from different points in my code. Commented Oct 16, 2018 at 14:17

1 Answer 1

8

The valueChanges event is fired after the new value is updated to the FormControl value, and before the change is bubbled up to its parent and ancestors. Therefore, you will have to access the value of the FormControl itself, not a field of the FormGroup value object.

console.log this.inputGroup.get('myControl').value inside the subscribe and it will be having the new value.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks Franklin, this was the correct answer! I'm very new to angular and apparently I did not properly understand the difference between the two. If I understand correctly: I was accessing the values as set in the FormGroup (basically: the values that are used to generate/populate the controls) instead of accessing the current data in the control itself. Am I correct?
@Master_T Initially the form control value gets updated and then it gets bubbled up to the parent and updates the form and value. And you were trying the access the value of the form (parent) which was not yet updated.
Thanks for the explanation, much appreciated

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.