Bogdan Daniel
Bogdan Daniel

Reputation: 2759

Angular - Input [value] bound to form control is not refreshing once with the form control value

In a reactive form approach, I have a slider which has a form control bound to it. When the slider is moves the form control value updates. I also have an input field near the slider which shows the value of the slider and can also update it by typing.

<input type="number" class="form-control" id="{{feature.name}}-input"
                [min]="0" [max]="100" [step]="1"
                (change)="onInputChange($event, feature)" [value]="featuresForm.get(feature.name)?.value.value">

And I have the following onInputChange method which updates the form control's value when the user changes the input:

onInputChange(event: any, feature: any) {
const input = this.featuresForm.get(feature.name);

if (event.target.value > 100) {
  input?.setValue({ value: 100 });
  return;
}
if (event.target.value < 0) {
  input?.setValue({ value: 0 });
  return;
}

input?.setValue({ value: event.target.value });
  }

Everything works fine if I input value between the 0 and 100, but something strange happens if I input values outside of that range.

For example:

  1. Input 105 - input value resets to 100
  2. Input 110 - input value stays at 110(or any other value that you type over 100), it does not reset anymore
  3. Input 50 - input value resets to 50, everything work as expected

I think that by executing input?.setValue({ value: 100 }); in a consecutive manner, input 105 and then 110, the form will not detect any change and it will therefore not update [value]="featuresForm.get(feature.name)?.value.value". Is there a way to fix this?

Edit: Stackblitz url: https://stackblitz.com/edit/angular-yb2vgj

Please assume that the first input would be a slider which has an input of type

new FormControl({value: 24}), and not new FormControl(24)

With the code that is present there and with the scenario posted above I would like to understand why the second input does not update properly after 2 consecutive inputs of over 100.

Upvotes: 2

Views: 6557

Answers (1)

Jasdeep Singh
Jasdeep Singh

Reputation: 8321

We can resolve it via many hacks, please find the below code. You can create an another property that will keep track of input form. We can use this property to update the slider form control value as well.

I hope it will help else i will recommend you to create a stackblitz instance.

myInputValue = 0;
onInputChange(event: any, feature: any) {
  const input = this.featuresForm.get(feature.name);

  this.myInputValue = (event.target.value > 100) ? 100 :
    (event.target.value < 0)? 0:
    event.target.value;

  input ? .setValue({
    value: this.myInputValue;
  });
}
<input type="number" class="form-control" id="{{feature.name}}-input" [min]="0" [max]="100" [step]="1" (change)="onInputChange($event, feature)" [value]="myInputValue">

You can also use setTimeout to forcefully initiate change detection.

onInputChange(event: any) {
    debugger;
    if (event.target.value > 100) {
      setTimeout(() => {
        this.featuresForm.get('slider').setValue(100)
        return;
      })
    }
    if (event.target.value < 0) {
      setTimeout(() => {
        this.featuresForm.get('slider').setValue(0)
      return;
      })
    }

    this.featuresForm.get('slider').setValue( event.target.value )
  }

Upvotes: 1

Related Questions