Автозаполнение не обнаруживает правильное значение из свойств объекта Angular - PullRequest
0 голосов
/ 20 января 2020

У меня огромный список counties и я хочу реализовать функцию автозаполнения. Я использую ту же форму для add нового клиента или update существующего клиента.

Теперь проблема в том, что при добавлении нового клиента моя программа работает отлично, но когда я обновляю ее В раскрывающемся списке округа он показывает countyId вместо name. Как этого добиться? см. изображения в следующем порядке:

Схема округа имеет вид

{
  countyId: number;
  name:string
}

Я пытаюсь использовать следующий код в html

<mat-form-field appearance="outline" fxFlex="50" class="pr-4">
    <mat-label>County</mat-label>
    <input type="text" placeholder="County" name="" matInput formControlName="countyId" [matAutocomplete]="auto">

    <mat-autocomplete autoActiveFirstOption #auto="matAutocomplete">
        <mat-option *ngFor="let county of filteredCounties | async" [value]="county.name">
            {{county.name}}
        </mat-option>
    </mat-autocomplete>
</mat-form-field>

и в моем файле компонента

import { Component, OnInit, Inject, ViewChild, AfterViewInit, ElementRef, ComponentRef } from '@angular/core';
import { FormGroup, FormControl, FormBuilder, Validators } from '@angular/forms';
import { Router, ActivatedRoute } from '@angular/router';
import { CustomerService } from '../../../../services/customer/customer.service';
import { CountyService } from '../../../../services/county/county.service';
import { SubCountyService } from '../../../../services/subCounty/sub-county.service';
import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import PNotify from 'pnotify/dist/es/PNotify';
import { Observable } from 'rxjs';
import { map, startWith } from 'rxjs/operators';

@Component({
  selector: 'app-new-customer',
  templateUrl: './new-customer.component.html',
  styleUrls: ['./new-customer.component.scss']
})

export class NewCustomerComponent implements OnInit {
  dataSending = false;
  customerId;
  updatePerson;
  updatedCustomer;
  ready = false;
  dialogView;
  ref: ComponentRef<any>;
  newCustomerForm: FormGroup;
  counties; // list of counties
  subCounties;
  filteredCounties: Observable<string[]>;

  constructor(
    private _formBuilder: FormBuilder,
    private router: Router,
    private route: ActivatedRoute,
    private customerService: CustomerService,
    private countyService: CountyService,
    private subCountyService: SubCountyService,
    public dialogRef: MatDialogRef<NewCustomerComponent>,
    @Inject(MAT_DIALOG_DATA) public display: any
  ) {
    this.dialogView = display.view;
    this.route.paramMap.subscribe((params) => {
      this.customerId = params.get('customerId');
      if (this.customerId) {
        this.customerService.getCustomer(this.customerId).subscribe((response) => {
          this.updatePerson = response;
          this.newCustomerForm = this._formBuilder.group({
            name: [this.updatePerson.name, Validators.required],
            nationalId: [this.updatePerson.nationalId, Validators.required],
            gender: [this.updatePerson.gender, Validators.required],
            phone1: [this.updatePerson.phone1],
            phone2: [this.updatePerson.phone2],
            bishopName: [this.updatePerson.bishopName, Validators.required],
            bishopPhone: [this.updatePerson.bishopPhone, Validators.required],
            countyId: [this.updatePerson.countyId, Validators.required],
            county: [this.updatePerson.county, Validators.required],
            subCountyId: [this.updatePerson.subCountyId, Validators.required],
            address: [this.updatePerson.address, Validators.required],
            additionalInfo: [this.updatePerson.additionalInfo],
            input1: [this.updatePerson.input1],
            input2: [this.updatePerson.input2],
            defaultingRecord: [''],
          });
          this.ready = true;
        });
      }
      else {
        this.ready = true;
        this.newCustomerForm = this._formBuilder.group({
          nationalId: ['', Validators.required],
          name: ['', Validators.required],
          gender: ['', Validators.required],
          phone1: [''],
          phone2: [''],
          county: [''],
          countyId: ['', Validators.required],
          subCountyId: ['', Validators.required],
          bishopName: ['', Validators.required],
          bishopPhone: ['', Validators.required],
          address: ['', Validators.required],
          additionalInfo: [''],
          input1: [''],
          input2: [''],
          defaultingRecord: [''],
        });
      }
    });
  }

  // tslint:disable:typedef
  ngOnInit() {
    // Getting the list of counties
    this.countyService.getCounties().subscribe((response) => {
      this.counties = response;
      this.newCustomerForm.patchValue({
        county: response
      });
      if (!this.customerId) {

        this.filteredCounties = this.newCustomerForm.get('county').valueChanges.pipe(
          startWith(''),
          map(value => typeof value === 'string' ? value : value.name),
          map(value => this._filter(value))
        );
      }
    }, error => {
      this.counties = [
        {
          "countyId": 63,
          "name": "Mombasa"
        },
        {
          "countyId": 64,
          "name": "Isiolo"
        },
        {
          "countyId": 65,
          "name": "Murang'a"
        },
        {
          "countyId": 66,
          "name": "Laikipia"
        },
        {
          "countyId": 67,
          "name": "Siaya"
        },
        {
          "countyId": 68,
          "name": "Kwale"
        },
        {
          "countyId": 69,
          "name": "Meru"
        },
        {
          "countyId": 70,
          "name": "Kiambu"
        },
        {
          "countyId": 71,
          "name": "Nakuru"
        },
        {
          "countyId": 72,
          "name": "Kisumu"
        },
        {
          "countyId": 73,
          "name": "Kilifi"
        },
        {
          "countyId": 74,
          "name": "Tharaka-Nithi"
        },
        {
          "countyId": 75,
          "name": "Turkana"
        },
        {
          "countyId": 76,
          "name": "Narok"
        },
        {
          "countyId": 77,
          "name": "Homa Bay"
        },
        {
          "countyId": 78,
          "name": "Tana River"
        },
        {
          "countyId": 79,
          "name": "Embu"
        },
        {
          "countyId": 80,
          "name": "West Pokot"
        },
        {
          "countyId": 81,
          "name": "Kajiado"
        },
        {
          "countyId": 82,
          "name": "Migori"
        },
        {
          "countyId": 83,
          "name": "Lamu"
        },
        {
          "countyId": 84,
          "name": "Kitui"
        },
        {
          "countyId": 85,
          "name": "Samburu"
        },
        {
          "countyId": 86,
          "name": "Kericho"
        },
        {
          "countyId": 87,
          "name": "Kisii"
        },
        {
          "countyId": 88,
          "name": "Taita-Taveta"
        },
        {
          "countyId": 89,
          "name": "Machakos"
        },
        {
          "countyId": 90,
          "name": "Trans Nzoia"
        },
        {
          "countyId": 91,
          "name": "Bomet"
        },
        {
          "countyId": 92,
          "name": "Nyamira"
        },
        {
          "countyId": 93,
          "name": "Garissa"
        },
        {
          "countyId": 94,
          "name": "Makueni"
        },
        {
          "countyId": 95,
          "name": "Uasin Gishu"
        },
        {
          "countyId": 96,
          "name": "Kakamega"
        },
        {
          "countyId": 97,
          "name": "Nairobi"
        },
        {
          "countyId": 98,
          "name": "Wajir"
        },
        {
          "countyId": 99,
          "name": "Nyandarua"
        },
        {
          "countyId": 100,
          "name": "Elgeyo-Marakwet"
        },
        {
          "countyId": 101,
          "name": "Vihiga"
        },
        {
          "countyId": 102,
          "name": "Mandera"
        },
        {
          "countyId": 103,
          "name": "Nyeri"
        },
        {
          "countyId": 104,
          "name": "Nandi"
        },
        {
          "countyId": 105,
          "name": "Bungoma"
        },
        {
          "countyId": 106,
          "name": "Marsabit"
        },
        {
          "countyId": 107,
          "name": "Kirinyaga"
        },
        {
          "countyId": 108,
          "name": "Baringo"
        },
        {
          "countyId": 109,
          "name": "Busia"
        }
      ];
    });
    // Getting a list of sub-counties
    this.subCountyService.getSubCounties().subscribe((response) => {
      this.subCounties = response;
    });
  }
  displayFn(county?: any): string | undefined {
    return county ? county.name : undefined
  }
  private _filter(value) {
    console.log('value: ', value);
    const filterValue = value.toLowerCase();
    return this.counties.filter(county => county.name.toLowerCase().indexOf(filterValue) === 0);
  }
  addCustomer(customer) {
    console.log('Value of customer form before setting is: ', this.newCustomerForm.value);
    const selectedCountyId = this.counties.filter(county => county.name === this.newCustomerForm.value.countyId)[0];
    console.log('CountyId: ', selectedCountyId);
    if (!selectedCountyId) {
      PNotify.error({
        title: 'Please selecte a valid county',
        minHeight: '75px'
      });
      return;
    }
    this.newCustomerForm.patchValue({
      countyId: selectedCountyId.countyId
    });
    customer.countyId = selectedCountyId.countyId;
    console.log('Value of customer form after setting is: ', this.newCustomerForm.value);
    this.dataSending = true;
    this.customerService.addCustomer(customer).subscribe((response) => {
      if (this.dialogView) {
        PNotify.success({
          title: 'Customer added Successfully',
          minHeight: '75px'
        });
        this.dialogRef.close();
      }
      else {
        PNotify.success({
          title: 'Customer added Successfully',
          text: 'Redirecting to list page',
          minHeight: '75px'
        });
        this.dataSending = false;
        document.getElementById('submitButton').style.display = 'initial';
        this.router.navigate(['searchcustomer']);
      }

    }, (error) => {
      console.log('Following error occured: ', error);
      PNotify.error({
        title: 'Error occured while adding customer',
        text: 'Failed to add new customer',
        minHeight: '75px'
      });
      this.dataSending = false;
    });
  }

  updateCustomer(customer) {
    this.dataSending = true;
    this.updatedCustomer = this._formBuilder.group({
      customerId: [this.customerId],
      nationalId: [customer.nationalId],
      name: [customer.name],
      gender: [customer.gender],
      phone1: [customer.phone1],
      phone2: [customer.phone2],
      countyId: [customer.countyId],
      subCountyId: [customer.subCountyId],
      address: [customer.address],
      additionalInfo: [customer.additionalInfo],
      bishopName: [customer.bishopName],
      bishopPhone: [customer.bishopPhone],
      input1: [customer.input1],
      input2: [customer.input2],
    });

    this.customerService.updateCustomer(this.updatedCustomer.value, this.customerId).subscribe((response) => {
      PNotify.success({
        title: 'Customer updated Successfully',
        text: 'Redirecting to list page',
        minHeight: '75px'
      });
      this.dataSending = false;
      this.router.navigate(['searchcustomer']);
    }, (error) => {
      console.log('An error occured while updating customer: ', error);
      PNotify.error({
        title: 'Error occured while updating customer',
        text: 'Failed to update customer',
        minHeight: '75px'
      });
      this.dataSending = false;
    });
  }
}



Картинки для лучшего понимания Image 1 Image 2 Image 3

1 Ответ

1 голос
/ 20 января 2020

Если вы введете идентификатор автозаполнения, это то, что он покажет. На вашем первом изображении, где вы говорите, что оно работает, оно выглядит так, как будто оно работает, но на самом деле оно не хранит countyId при выборе, а свойство name, которое вы установили как value. Я бы предположил, что на самом деле это тоже идентификатор, который вы хотите хранить там.

Самое чистое решение, на мой взгляд, это хранить весь объект округа. Поэтому я бы предложил следующее:

<input type="text" matInput formControlName="county" [matAutocomplete]="auto">

<mat-autocomplete autoActiveFirstOption #auto="matAutocomplete" [displayWith]="displayFn">
  <mat-option *ngFor="let county of filteredCounties | async" [value]="county">
    {{county.name}}
  </mat-option>
</mat-autocomplete>

, с этим я удалил countyId formcontrol и вместо этого добавил county, который хранит весь объект, и добавил displayWith, чтобы показать свойство name округ.

Затем измените valueChanges, чтобы проверить, набрал ли пользователь объект или ему дали объект:

// add the correct name of your form
this.filteredCounties = this.myForm
  .get("county")
  .valueChanges.pipe(
    startWith(""),
    map(value => typeof value === 'string' ? value : value.name),
    map(value => this._filter(value))
  );

и displayFn, который показан в шаблоне:

// don't use 'any' !!
displayFn(county?: any): string | undefined {
  return county ? county.name : undefined
}

Так что теперь осталась только опция, где вы хотите создать форму редактирования. Если у вас есть только свойство countyId, вы можете использовать find для добавления правильного объекта. Здесь, в этом примере, я настроил его на создание, но вы, возможно, будете использовать setValue(), но идея та же!

// replace 2 with the variable/prop you have the desired id
county: [this.counties.find(x => x.countyId === 2)],

Так что теперь у вас есть весь объект. При отправке формы и если вы хотите, чтобы countyId только из элемента управления формы, вы можете получить к нему доступ: this.myForm.get('county').value.countyId.

STACKBLITZ с вышеуказанный код.

...