autocomplete display id_product using Angular6

2019-08-22 01:15发布

问题:

Next to this post I can post this result ["1", "2", "3"] but I have another problem.

When I select product, in view show id, 1, 2 and 3, not name of product. like in image

I change function updateForm() like below:

products: Products[] = []; 

 updateForm(ev: any, idd: any, componentid: any) {
    if (ev.isUserInput) {
      if (componentid === 'products_name') {
      this.prodId = idd;
      for (let i = 0; i < this.products.length; i++) {
      if (this.products[i].products_id=== idd) {
      console.log(this.products[i].products_name) //in this part I can see product name
    this.myForm.controls.products_id.setValue(this.products[i].products_name)
          }
        }
      } else {
        console.log('error');
      }
    }
  }

And my html code is Like this:

  <div class="row">
    <div class="input-field col s10">
      <div class="form-group">
        <div formArrayName="products_id">
          <div *ngFor="let p of myForm.get('products_id').value; let i = index">
            <input  formControlName="{{i}}" id="products_id" type="text"  aria-label="Number" matInput
              [matAutocomplete]="auto">
            <mat-autocomplete autoActiveFirstOption #auto="matAutocomplete" [displayWith]="displayWith">
              <mat-option (onSelectionChange)="updateForm($event, pro.products_id, 'products_name')" *ngFor="let pro of filteredProduct | async"
                [value]="pro.products_id">
                {{pro.products_name}} 
              </mat-option>
            </mat-autocomplete>
            <div class="button-left">
                <button *ngIf="myForm.controls.products_id.value.length > 1" type="button" class="fa" (click)="onRemoveItem(i)">-</button>
              </div>
          </div>

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

Any idea please? How to display products_name ?

Thank you!

回答1:

There was an issue with your Template and with your updateFormProducts method.

Here are the fixes:

updateFormProducts(ev: any, idd: any, componentid: any, index) {
  console.log(ev.source.viewValue)
  console.log(componentid)
  if (ev.isUserInput) {
    if (componentid === 'products_id') {
      console.log(ev.source.viewValue);
      ( < FormArray > this.myform.get('products_id')).at(index).patchValue(ev.source.viewValue);
    } else {
      console.log('error');
    }
  }
}

In this method, you'll need to pass index of the State field in your FormArray and then call patchValue on only that field which you'll be able to get using (<FormArray>this.myform.get('products_id')).at(index)

Then in your template, you also need to fix a few things. Here's your updated template:

<form [formGroup]="myform" (ngSubmit)="onAddprod()" class="example-form">
  <div class="form-group">
    <div formArrayName="products_id">
      <div *ngFor="let s of myform.get('products_id').controls; let i = index">
        <mat-form-field class="example-full-width">
          <input [formControlName]="i" matInput placeholder="State" aria-label="State" [matAutocomplete]="auto">

          <mat-autocomplete #auto="matAutocomplete" [displayWith]="displayWith">
            <mat-option *ngFor="let state of filteredStates | async" (onSelectionChange)="updateFormProducts($event, state.products_name, 'products_id', i)" [value]="state.products_id">
              <span>{{state.products_name}}</span>
            </mat-option>
          </mat-autocomplete>

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

  <br>

  <div class="input-field col s2">
    <input formControlName="unit_price" id="unit_price" type="text">
  </div>
  <button type="submit" class="btn waves-effect waves-light">Register</button>
</form>

Here's an Updated StackBlitz for your ref.

UPDATE

For your issue, you might want to do this:

In template create a getter:

get productIdFormArray () {
  return (<FormArray>this.myform.get('products_id')).controls;
}

And in the template, you can use productIdFormArray to iterate over through the FormArray:

...
<div *ngFor="let s of productIdFormArray; let i = index">
  <mat-form-field class="example-full-width">
...

You can find the changes in the Updated StackBlitz as well.