简体   繁体   中英

Getting 'TypeError: Cannot read property 'errors' of undefined' in my Angular Form

I want to have a Reactive form for creating clients, however, I get this error in the console when I serve my app:

TypeError: Cannot read property 'errors' of undefined

It is pointing to the first <li> element of this block:

  <ul class="help-block">
      <li *ngIf="form.controls.email.errors?.required && form.controls.email.dirty">Required</li>
      <li *ngIf="(form.controls.email.errors?.minlength || form.controls.email.errors?.maxlength) && form.controls.email.dirty">Minimum chars: 5, maximum 35</li>

    </ul>

full form code:

    <form style="border:1px solid" [formGroup]="form" 
    (submit)="onRelatieSubmit()">
    <h4> New client </h4>
    <div class="form-group">

      <label for="company">Company</label>
      <div class="col-5">
        <input  [ngClass]="{'is-invalid': (form.controls.company.errors && 
    form.controls.company.dirty),
        'is-valid': !form.controls.company.errors}" class="form-control" type="text" name="company" (autocomplete)="off" placeholder="Name" formControlName="company" (blur)="checkUsername()"/>
        <ul class="help-block">
          <li *ngIf="form.controls.company.errors?.required && form.controls.company.dirty">Required</li>
          <li *ngIf="(form.controls.company.errors?.minlength || form.controls.company.errors?.maxlength) && form.controls.company.dirty">Minimum chars: 5, maximum 25</li>


        </ul>
      </div>
    </div>
    <div class="form-group">
      <label for="addressLineOne">Address</label>
      <div class="col-5">
        <input [ngClass]="{'is-invalid': (form.controls.addressLineOne.errors && form.controls.addressLineOne.dirty) ,
     'is-valid': !form.controls.addressLineOne.errors}" id="addressLineOne" class="form-control" type="text" name="addressLineOne" (autocomplete)="off" placeholder="Address" formControlName="addressLineOne" (blur)="checkEmail()"/>

        <ul class="help-block">
          <li *ngIf="form.controls.addressLineOne.errors?.required && form.controls.addressLineOne.dirty">Requiredt</li>



        </ul>
      </div>
    </div>
    <div class="form-group">
      <label for="city">City</label>
      <div class="col-5">
        <input  [ngClass]="{'is-invalid': (form.controls.city.errors && form.controls.city.dirty), 'is-valid': !form.controls.city.errors}" id="city" class="form-control" type="text" name="city" (autocomplete)="off" placeholder="City" formControlName="city"/>
        <ul class="help-block">
          <li *ngIf="form.controls.city.errors?.required && form.controls.city.dirty">Requiredt</li>

        </ul>
      </div>
    </div>

    </div>


<div class="form-group">
      <label for="email">Email</label>
      <div class="col-5">

        <input [ngClass]="{'is-invalid': (form.controls.email.errors && form.controls.email.dirty),
     'is-valid': !form.controls.email.errors}" id="email" class="form-control" type="text" name="email" (autocomplete)="off" placeholder="Email" formControlName="email"/>

        <ul class="help-block">
          <li *ngIf="form.controls.email.errors?.required && form.controls.email.dirty">Required</li>
          <li *ngIf="(form.controls.email.errors?.minlength || form.controls.email.errors?.maxlength) && form.controls.email.dirty">Minimum chars: 5, maximum 35</li>


        </ul>
      </div>
    </div>




    <div class="form-group">
      <label for="country">Country</label>
      <div class="col-5">
        <input  [ngClass]="{'is-invalid': (form.controls.country.errors && form.controls.country.dirty) , 'is-valid': !form.controls.country.errors}" id="country"  class="form-control" type="text" name="country" (autocomplete)="off" placeholder="Country" formControlName="country"/>
        <ul class="help-block">
          <li *ngIf="form.controls.country.errors?.required && form.controls.country.dirty">Required</li></ul>

      </div>
    </div>

    <div class="form-group">
      <label for="postalCode">Postal code</label>
      <div class="col-5">
        <input  [ngClass]="{'is-invalid': (form.controls.postalCode.errors && form.controls.postalCode.dirty) , 'is-valid': !form.controls.postalCode.errors}" id="postalCode"  class="form-control" type="text" name="postalCode" (autocomplete)="off" placeholder="Postal Code" formControlName="postalCode"/>
        <ul class="help-block">
          <li *ngIf="form.controls.postalCode.errors?.required && form.controls.postalCode.dirty">Required</li></ul>

      </div>
    </div>

    <div class="form-group">
      <label for="phone">Phone</label>
      <div class="col-5">
        <input  [ngClass]="{'is-invalid': (form.controls.phone.errors && form.controls.phone.dirty), 'is-valid': !form.controls.phone.errors}" id="phone"  class="form-control" type="text" name="phone" (autocomplete)="off" placeholder="Aantal kilometers" formControlName="phone"/>
        <ul class="help-block">
          <li *ngIf="form.controls.phone.errors?.required && form.controls.phone.dirty">Required</li></ul>

      </div>
    </div>

    <input [disabled]="!form.valid || processing" type="submit" class="btn btn-primary" value="Submit" />
  </form>

this is my CreateForm function in `client.component.ts'

createForm() {
this.form = this.formBuilder.group(
  {
    company: ['', Validators.compose([
      Validators.required,
      Validators.minLength(5),
      Validators.maxLength(35),


    ])],
    addressLineOne: ['', Validators.compose([
      Validators.required,
      Validators.minLength(3),
      Validators.maxLength(35),

    ])],
    city: ['', Validators.compose([
      Validators.required,
      Validators.minLength(8),
      Validators.maxLength(35),

    ])],
    country: ['', Validators.compose([
      Validators.required,
      Validators.minLength(3),
      Validators.maxLength(35),

    ])],
    postalCode: ['', Validators.compose([
      Validators.required,
      Validators.minLength(3),
      Validators.maxLength(35),

    ])],
    phone: ['', Validators.compose([
      Validators.required,
      Validators.minLength(3),
      Validators.maxLength(35),

    ])],
    email: ['', Validators.compose([
      Validators.required,
      Validators.minLength(3),
      Validators.maxLength(35),

    ])],

  }
)

}

Why is it saying that email is undefined? I dont get it, I have declared it in the formbuilder.group If you need more info, please let me know

In.ts write

 get addressLineOne() {
    return this.form.get('addressLineOne');

}

and in html:

<ul class="help-block">
      <li *ngIf="addressLineOne.errors?.required && addressLineOne.dirty">Requiredt</li>
</ul>

Try this to see if the error not persist and the form is render:

<ul class="help-block" *ngIf="form.controls.email">
      <li *ngIf="form.controls.email.errors?.required && form.controls.email.dirty">Required</li>
      <li *ngIf="(form.controls.email.errors?.minlength || form.controls.email.errors?.maxlength) && form.controls.email.dirty">Minimum chars: 5, maximum 35</li>

    </ul>

Instead of adding all the error messages by hand to your html you can try something else, this might help solving the problem since it's covering all possible errors and making more organized calls from the html.

(This is just a sample code, so please modify for your requirements)

In your.component file add a new property and add messages for all the requirements. important part, if number of requirements and the messages (and the names of type) should match.

validation_messages = {
      'name': [
        { type: 'required', message: 'Name is required.' }
      ],
      'email': [
        { type: 'required', message: 'Email is required.' },
        { type: 'email', message: 'Please enter a valid email.' }
      ],
      'password': [
        { type: 'required', message: 'Password is required.' },
        { type: 'minlength', message: 'Password must be at least 5 characters long.' },
        { type: 'pattern', message: 'Your password must contain at least one uppercase, one lowercase, and one number.' }
  };

And in your html file after each input block:

(in this example [formGroup]="validations_form")

<div class="validation-errors">
   <ng-container *ngFor="let validation of validation_messages.name">
      <div class="error-message"
          *ngIf="validations_form.get('name').hasError(validation.type) 
          && (validations_form.get('name').dirty 
          || validations_form.get('name').touched)">
          {{ validation.message }}
      </div>
   </ng-container>
</div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM