Невозможно прочитать свойство hasError из undefined во вложенной группе форм в угловом HTML

Я продолжаю получать сообщение об ошибке Cannot read property 'hasError' of undefined в CreateWorkOrderDialogComponent_Template (create-work-order-dialog.component.html: 69) при создании проверки для моей вложенной formGroup. Я пытался получить контроль формы с помощью приведенного ниже кода, но пока безуспешно.

    <mat-error *ngIf="form.get['client.name'].hasError('required')"
        >Required
      </mat-error>

Моя форма с вложенными formGroups:

<div #container>
  <form
    [formGroup]="form"
    (ngSubmit)="save()"
    data-test="createFollowUpDialog"
    autocomplete="off"
  >
    <h1 mat-dialog-title>Maak een nieuwe werkorder aan</h1>
    <mat-dialog-content>
      <div class="row mt-3">
        <div class="col-md-12">
          <h2>Werkorder informatie</h2>
          <mat-form-field class="input">
            <mat-label>Omschrijving van het probleem</mat-label>
            <input
              formControlName="leakageReason"
              tabindex="1"
              autocomplete="off"
              matInput
              placeholder="Omschrijving van probleem"
              matTooltip="Omschrijving van het probleem"
            />
            <mat-error
              *ngIf="form.controls['leakageReason'].hasError('required')"
              >Verplicht
            </mat-error>
          </mat-form-field>
        </div>
      </div>
      <div class="row mt-3">
        <div class="col-md-12">
          <mat-form-field class="input">
            <mat-label>Projectnummer</mat-label>
            <input
              formControlName="projectNumber"
              tabindex="2"
              autocomplete="off"
              matInput
              placeholder="Projectnummer"
            />
            <mat-error
              *ngIf="form.controls['projectNumber'].hasError('required')"
              >Verplicht
            </mat-error>
          </mat-form-field>
        </div>
      </div>
      <div formGroupName="client">
        <h3>Gegevens van de opdrachtgever</h3>
        <div class="row mt-3">
          <div class="col-md-12">
            <mat-form-field class="input">
              <mat-label>Naam opdrachtgever</mat-label>
              <input
                formControlName="name"
                tabindex="2"
                autocomplete="off"
                matInput
                matTooltip="Naam van de opdrachtgever"
                placeholder="Naam opdrachtgever"
              />
              <mat-error *ngIf="form.get['client.name'].hasError('required')"
                >Verplicht
              </mat-error>
            </mat-form-field>
          </div>
        </div>
        <div class="row mt-3">
          <div class="col-md-12">
            <mat-form-field class="input">
              <mat-label>Telnr. van opdrachtgever</mat-label>
              <input
                formControlName="phoneNumber"
                tabindex="2"
                autocomplete="off"
                matInput
                matTooltip="Telnr. van de opdrachtgever"
                placeholder="Telnr. opdrachtgever"
              />
            </mat-form-field>
          </div>
        </div>
      </div>
      <div formGroupName="customer">
        <h3>Gegevens van de klant</h3>
        <div class="row mt-3">
          <div class="col-md-12">
            <mat-form-field class="input">
              <mat-label>Naam Klant</mat-label>
              <input
                formControlName="name"
                tabindex="2"
                autocomplete="off"
                matInput
                matTooltip="Naam van de klant"
                placeholder="Naam klant"
              />
            </mat-form-field>
          </div>
        </div>
        <div class="row mt-3">
          <div class="col-md-8">
            <mat-form-field class="input">
              <mat-label>Adres van klant</mat-label>
              <input
                formControlName="street"
                tabindex="2"
                autocomplete="off"
                matInput
                matTooltip="Straat van de klant"
                placeholder="straat klant"
              />
            </mat-form-field>
          </div>
          <div class="col-md-2">
            <mat-form-field class="input addressWidth">
              <mat-label>Huisnr.</mat-label>
              <input
                formControlName="houseNumber"
                tabindex="2"
                autocomplete="off"
                matInput
                matTooltip="Huisnummer"
                placeholder="Huisnr."
              />
            </mat-form-field>
          </div>
          <div class="col-md-2">
            <mat-form-field class="input addressWidth">
              <mat-label>toevoeging</mat-label>
              <input
                formControlName="houseNumberExt"
                tabindex="2"
                autocomplete="off"
                matInput
                matTooltip="Huisnummer toevoeging"
                placeholder="toevoeging"
              />
            </mat-form-field>
          </div>
        </div>
        <div class="row mt-3">
          <div class="col-md-4">
            <mat-form-field class="input zipCodeWidth">
              <mat-label>Postcode</mat-label>
              <input
                formControlName="zipCode"
                tabindex="2"
                autocomplete="off"
                matInput
                matTooltip="Postcode"
                placeholder="Postcode"
              />
            </mat-form-field>
          </div>
          <div class="col-md-4">
            <mat-form-field class="input">
              <mat-label>Plaats</mat-label>
              <input
                formControlName="city"
                tabindex="2"
                autocomplete="off"
                matInput
                matTooltip="Plaats"
                placeholder="Plaats"
              />
            </mat-form-field>
          </div>
        </div>
      </div>
      <div class="row mt-3">
        <div class="col-md-12">
          <mat-form-field class="datepicker">
            <mat-label>Inspectiedatum </mat-label>
            <input
              matInput
              formControlName="dateInspection"
              tabindex="3"
              [matDatepicker]="pickerIn"
            />
            <mat-datepicker-toggle
              tabindex="-1"
              matSuffix
              [for]="pickerIn"
            ></mat-datepicker-toggle>
            <mat-datepicker #pickerIn></mat-datepicker>
          </mat-form-field>
        </div>
      </div>
      <div class="row mt-3">
        <div class="col-md-12">
          <mat-form-field class="input">
            <mat-label>Status werkorder</mat-label>
            <mat-select formControlName="status" name="status" tabindex="4">
              <mat-option
                *ngFor="let status of statusWerkOrder"
                [value]="status"
              >
                {{ status }}
              </mat-option>
            </mat-select></mat-form-field
          >
        </div>
      </div>
      <div class="row mt-3">
        <div class="col-md-12">
          <mat-slide-toggle
            color="primary"
            formControlName="followupInspection"
            tabindex="5"
            >Opvolgmelding?</mat-slide-toggle
          >
        </div>
      </div>
      <div class="row mt-3">
        <div class="col-md-12">
          <mat-slide-toggle
            color="primary"
            formControlName="clientPresent"
            tabindex="6"
            >Is de klant aanwezig?</mat-slide-toggle
          >
        </div>
      </div>
      <div class="row mt-3">
        <div class="col-md-12">
          <mat-slide-toggle
            color="primary"
            formControlName="visibleWaterDamage"
            tabindex="7"
            >Zichtbare waterschade?</mat-slide-toggle
          >
        </div>
      </div>
      <div class="row mt-3">
        <div class="col-md-12">
          <mat-form-field class="input">
            <mat-label>Duur waterschade</mat-label>
            <input
              formControlName="visibleWaterDamagePeriod"
              tabindex="8"
              autocomplete="off"
              matInput
              matTooltip="Duur waterschade (dag, week, etc.)"
              placeholder="Duur waterschade"
            />
          </mat-form-field>
        </div>
      </div>
      <div class="row mt-3">
        <div class="col-md-12">
          <mat-form-field class="input">
            <mat-label>Soort gebouw</mat-label>
            <mat-select
              formControlName="buildingType"
              name="buildingType"
              tabindex="9"
            >
              <mat-option
                *ngFor="let buildingType of buildingTypes"
                [value]="buildingType"
              >
                {{ buildingType }}
              </mat-option>
            </mat-select></mat-form-field
          >
        </div>
      </div>
      <div class="row mt-3">
        <div class="col-md-12">
          <mat-form-field class="input">
            <mat-label>Renovatie jaar</mat-label>
            <input
              formControlName="renovatedYear"
              tabindex="10"
              autocomplete="off"
              matInput
              placeholder="Renovatie jaar"
              matTooltip="Renovatie jaar van het object"
            />
          </mat-form-field>
        </div>
      </div>
      <div class="divider"></div>
    </mat-dialog-content>
    <mat-dialog-actions class="d-flex">
      <button
        mat-raised-button
        type="submit"
        color="primary"
        tabindex="11"
        class="align-items-end"
        matTooltip="Na opslaan worden de openstaande meldingen ververst zodat de melding direct ingepland kan worden"
      >
        Opslaan
      </button>
      <button
        mat-raised-button
        tabindex="12"
        [mat-dialog-close]="true"
        data-test="cancelCloseDialog"
        class="align-items-end"
      >
        Annuleren
      </button>
    </mat-dialog-actions>
  </form>
</div>

Мой машинописный текст / файл компонента, в котором я создаю форму с помощью formbuilder, выглядит так:

 private buildForm() {
    this.form = this.formBuilder.group({
      projectNumber: new FormControl(this.data?.projectNumber, [
        Validators.required,
      ]),
      leakageReason: new FormControl(this.data?.leakageReason, [
        Validators.required,
      ]),
      dateInspection: new FormControl(this.data?.dateInspection, []),
      followupInspection: new FormControl(this.data?.followupInspection, []),
      clientPresent: new FormControl(this.data?.clientPresent, []),
      visibleWaterDamage: new FormControl(this.data?.visibleWaterDamage, []),
      visibleWaterDamagePeriod: new FormControl(
        this.data?.visibleWaterDamagePeriod,
        []
      ),
      buildingType: new FormControl(this.data?.buildingType, []),
      renovatedYear: new FormControl(this.data?.renovatedYear, []),
      status: new FormControl(this.data?.status, []),
      client: this.formBuilder.group({
        name: new FormControl(this.data?.client.name, [Validators.required]),
        contactPerson: new FormControl(this.data?.client.contactPerson),
        email: new FormControl(this.data?.client.email),
        phoneNumber: new FormControl(this.data?.client.name),
        street: new FormControl(this.data?.client.street),
        houseNumber: new FormControl(this.data?.client.houseNumber),
        houseNumberExt: new FormControl(this.data?.client.houseNumberExt),
        zipCode: new FormControl(this.data?.client.zipCode),
        city: new FormControl(this.data?.client.city),
        attribute: new FormControl(this.data?.client.attribute),
      }),
      customer: this.formBuilder.group({
        name: new FormControl(this.data?.customer.name, []),
        contactPerson: new FormControl(this.data?.customer.contactPerson),
        companyName: new FormControl(this.data?.customer.companyName),
        street: new FormControl(this.data?.customer.street),
        houseNumber: new FormControl(this.data?.customer.houseNumber),
        houseNumberExt: new FormControl(this.data?.customer.houseNumberExt),
        zipCode: new FormControl(this.data?.customer.zipCode),
        city: new FormControl(this.data?.customer.city),
        phoneNumber: new FormControl(this.data?.customer.phoneNumber, []),
      }),
    });
  }

Может ли кто-нибудь помочь мне, как это сделать правильно? Большое спасибо, Пит


person PeteBaser    schedule 27.06.2020    source источник
comment
AbstractControl#get (от которого FormGroup наследуется) на самом деле является функцией, которая возвращает элемент управления, который вы пытается получить из указанного вами аргумента. Вы собираетесь использовать FormGroup#controls, который представляет собой набор элементов управления, объявленных как объект.   -  person Edric    schedule 27.06.2020


Ответы (1)


Как я уже упоминал в своем комментарии:

AbstractControl#get (от которого FormGroup наследуется) на самом деле является функцией, которая возвращает элемент управления, который вы пытается получить из указанного вами аргумента. Вы собираетесь использовать FormGroup#controls, который представляет собой набор элементов управления, объявленных как объект.

Поэтому вам следует изменить свой код на:

<mat-error *ngIf="form.get('client.name')?.hasError('required')">
  Required
</mat-error>

Or:

<mat-error *ngIf="form.controls['client.name'].hasError('required')">
  Required
</mat-error>
person Edric    schedule 27.06.2020