Y_Lakdime
Y_Lakdime

Reputation: 825

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

Upvotes: 0

Views: 4725

Answers (3)

Fulya D.
Fulya D.

Reputation: 592

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>

Upvotes: 0

FedG
FedG

Reputation: 1301

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>

Upvotes: 1

German Quinteros
German Quinteros

Reputation: 1930

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>

Upvotes: 1

Related Questions