6

I am using Reactive forms with mat autocomplete. I used autocomplete in other parts of my app but i can't figure this out. I have a formarray which adds an input every time I want to add a new sensor in my case. autocomplete works fine in my first input but when I try to add more inputs an error is shown : Error: Must supply a value for form control at index: 1

HTML:

<div class="row">
    <div class="input-field col s10">
      <div class="form-group">
        <div formArrayName="sensors_id">
          <div *ngFor="let sensor of addHomeboxPForm.get('sensors_id')['controls']; let i = index">
            <br>
            <input formControlName="{{i}}" type="text" placeholder="Select Sensor" aria-label="Number" matInput [matAutocomplete]="auto1">
            <mat-autocomplete autoActiveFirstOption #auto1="matAutocomplete" [displayWith]="displayWith" >
              <mat-option (onSelectionChange)="updateForm($event, [sensor.sensors_id], 'sensors_id')" *ngFor="let sensor of filteredOptionsS | async" [value]="sensor.sensor_serial">
                {{sensor.sensor_serial}}
              </mat-option>
            </mat-autocomplete>
            <div class="button-left">
              <button *ngIf="addHomeboxPForm.controls.sensors_id.value.length > 1" type="button" class="fa" (click)="onRemoveItem(i)">RemoveSensor</button>
            </div>
          </div>
        </div>
      </div>


<div class="input-field col s2">
        <button type="button" class="btn" (click)="onAddItem()">AddSensor</button>
      </div>

TS:

formarray: 'sensors_id': this.fb.array([], Validators.required),

  updateForm(ev: any, idd: any, componentid: any) {

    if (ev.isUserInput) {
      if (componentid === 'sensors_id') {
        this.sensorId = idd;
        this.addHomeboxPForm['controls']['sensors_id'].setValue([ev.source.value])
      }
    }
  }

  onAddItem() {
    (<FormArray>this.addHomeboxPForm.controls['sensors_id']).push(new FormControl('', Validators.required));
  }

  onRemoveItem(index: number) {
    (<FormArray>this.addHomeboxPForm.controls['sensors_id']).removeAt(index);
  }

I am new to this so i am sorry if i am not that clear..but i havent found a solution yet

live-love
  • 48,840
  • 22
  • 240
  • 204
Aldo Abazi
  • 275
  • 2
  • 5
  • 12

3 Answers3

0

you fortmcontrolName should be defined in your component before you use it in the template html.

I see you have used <input formControlName="{{i}}" which is not valid as Angular is not able to find this formControl/field where the reactive form was declared initially.

After you create the control in the component class, you must associate it with a form control element in the template. Update the template with the form control using the formControl binding provided by FormControlDirective included in ReactiveFormsModule.

You can read more about reactive forms here:

Hope it helps.

nircraft
  • 8,242
  • 5
  • 30
  • 46
0

This error could be because you forgot to set the setValue function to an array, and instead you set it to an object (note the brackets []):

Example: Here you would get the error. Wrong:

this.checkoutForm.get('items').setValue({
  itemId: ['1aa'],
  itemName: ['2aa'],
  itemDesc: ['3bb'],
  itemDone: ['', Validators.requiredTrue]
});

Right:

this.checkoutForm.get('items').setValue([{
  itemId: ['1aa'],
  itemName: ['2aa'],
  itemDesc: ['3bb'],
  itemDone: ['', Validators.requiredTrue]
}]);

html:

<div class="form-group">
        <label for="exampleInputPassword1">Items</label>
        <div class='col-sm-10' formArrayName="items">
            <div *ngFor="let item of checkoutForm.controls.items['controls']; let i=index" [formGroupName]="i">
                <a [routerLink] (click)="removeitem(i)">remove</a>
                <input class="form-control" type="text" formControlName="itemId" id=task{{i}}>
                <input class="form-control" type="text" formControlName="itemName" id="task{{i}}">
                <input class="form-control" type="text" formControlName="itemDesc" id="task{{i}}">
                <input type="checkbox" formControlname="itemDone">Mark as Done
            </div>
        </div>
    </div>
live-love
  • 48,840
  • 22
  • 240
  • 204
0

While updating, use patchValue() method instead of setValue() method.

In your case, it will be -

    updateForm(ev: any, idd: any, componentid: any) {

    if (ev.isUserInput) {
      if (componentid === 'sensors_id') {
        this.sensorId = idd;
        this.addHomeboxPForm['controls']['sensors_id'].patchValue([ev.source.value])
      }
    }
  }

  onAddItem() {
    (<FormArray>this.addHomeboxPForm.controls['sensors_id']).push(new FormControl('', Validators.required));
  }

  onRemoveItem(index: number) {
    (<FormArray>this.addHomeboxPForm.controls['sensors_id']).removeAt(index);
  }