Daner
Daner

Reputation: 91

Material Autocomplete does'nt work after adding MatInput fields dynamically but before adding it works and populates

The code works for the first default matInput field and populates the suggestion list during the input change however when I add new fields to the form the suggestion list does not work and stops during the input change.

<form
  [formGroup]="feasibilityForm"
  (ngSubmit)="onSubmit(feasibilityForm.value)"
>
  <mat-form-field
    [style.width.%]="100"
    formArrayName="serviceNames"
    *ngFor="let service of serviceNames.controls; let i = index"
  >
    <mat-label> Service Activity </mat-label>
    <input
      [formControlName]="i"
      matInput
      type="text"
      [matAutocomplete]="auto"
    />
    <mat-autocomplete #auto="matAutocomplete">
      <mat-option
        *ngFor="let item of filteredOptions"
        [value]="item.Service"
      >
        {{ item.Service }}
      </mat-option>
    </mat-autocomplete>
  </mat-form-field>
  <div class="form-element">
    <button mat-flat-button color="primary" type="submit">Primary</button>
  </div>
</form>

The purpose is to add matInput fields dynamically to the form and autoComplete the suggestion list for each matInput field added.

options = [];

  feasibilityForm;
  filteredOptions;
  title = 'my-app';

  constructor(private service: MyService, private formBuilder: FormBuilder) {

  }
  ngOnInit() {
    this.initForm();
    this.getNames();
    this.service.getLocalData().subscribe(data => {
      console.log(data)
    })
  }

  initForm() {
    this.feasibilityForm = this.formBuilder.group({
      serviceNames: this.formBuilder.array([this.formBuilder.control('')]),
    })

    this.feasibilityForm.get('serviceNames').valueChanges.subscribe((response: any) => {
      console.log('data is ', response);
      this.filterData(response);
    })
  }

  get serviceNames() {
    return this.feasibilityForm.get('serviceNames') as FormArray;
  }

  addServiceName() {
    this.serviceNames.push(this.formBuilder.control(''));
    this.getNames();
    this.filteredOptions = [];
  }

  onSubmit(value) {
    console.log(this.serviceNames.value)
  }

  filterData(enteredData) {
    this.filteredOptions = this.options.filter((item) => {
      console.log(item.Service)
      return item.Service.toString().toLowerCase().indexOf(enteredData.toString().toLowerCase()) > -1
    })
  }

  getNames() {
    this.service.getLocalData().subscribe((response: any) => {
      this.options = response;
      this.filteredOptions = response;
    })
  }

Upvotes: 1

Views: 187

Answers (1)

Jimmy
Jimmy

Reputation: 1419

So the issue is from your filterData. You loop through the options instead of the enteredData.

The reason is enteredData will be come an array as you add more input.

Let's go with a small example: options = ['1','2','3']

  1. With 1 input: enteredData = [1] => toString returns '1'. options.indexOf('1') returns true.
  2. Now you add 1 more input => enteredData = ['1','1'] (assume you enter your text into both inputs) => toString returns '1,1' => options.indexOf('1,1') which will always return -1.

Upvotes: 1

Related Questions