0

I'm having a heck of a time understanding something that should be easy. Form validation. I'm using reactive forms for the first time. I'm using Form Builder. I've got a nested set of controls. In general, I'm assuming you create a set of controls with validation, then check for those in the template. I'm able to submit the form but keep getting errors when trying to create validation messages.


------ TEMPLATE -------

<div class="container">
  <div class="row">
    <div class="col-sm">

      <!-- Begin card -->
      <div class="card border">
        <div class="card-header bg-light text-primary">
          <h3>My Account</h3>
        </div>
        <div class="card-body border border-light">
          <!-- CHANGE PASSWORD BUTTON -->
          <div class="row">
            <div class="col-sm">
              <button class="btn btn-success" (click)="goToChangePassword()">Change Password</button>
            </div>
          </div>
          <!-- Begin Form -->
          <form *ngIf="user; else loading" [formGroup]="accountForm" (ngSubmit)="updateUser()">
            <hr>
            <!-- Phone -->
            <fieldset formGroupName="phone">
              <div class="form-row">
                <div class="form-group col-sm">
                  <label>Home Phone</label>
                  <input type="number" class="form-control" formControlName="home">
                  <div *ngIf="isSubmitted && fControls.home.errors" class="invalid-feedback">
                    <div *ngIf="fControls.home.errors.minlength">10 characters min</div>
                  </div>
                </div>
                <div class="form-group col-sm">
                  <label>Mobile Phone</label>
                  <input type="number" class="form-control" formControlName="mobile">
                  <div *ngIf="isSubmitted && fControls.mobile.errors" class="invalid-feedback">
                    <div *ngIf="fControls.mobile.errors.minlength">10 characters min</div>
                  </div>
                </div>
                <div class="form-group col-sm">
                  <label>Extension</label>
                  <input type="number" class="form-control" formControlName="extension">
                  <div *ngIf="isSubmitted && fControls.extension.errors" class="invalid-feedback">
                    <div *ngIf="fControls.extension.errors.maxlength">5 chartacters max</div>
                  </div>
                </div>
              </div>
            </fieldset>

            <!-- BIRTHDAY -->
            <fieldset formGroupName="birthday">
              <div class="form-row">
                <div class="form-group col-sm-3">
                  <label>Birthday Month</label>
                  <input type="number" class="form-control" formControlName="month">
                </div>
                <div class="form-group col-sm-3">
                  <label>Birthday Day</label>
                  <input type="number" class="form-control" formControlName="day">
                </div>
              </div>
            </fieldset>
            <hr />

            <!-- BUTTONS -->
            <div class=" form-row">
              <button type="submit" class="btn btn-success mr-3" [disabled]="!accountForm.valid">Update</button>
              <button class="btn btn-danger" (click)="cancel()">Cancel</button>
            </div>


            <!-- End form -->
          </form>
        </div>
      </div>
    </div>
  </div>
</div>

<!-- LOADING TEMPLATE -->
<ng-template #loading>
  Loading User...
</ng-template>



------ TS --------

import { Component, OnInit } from '@angular/core';
import { UserService } from 'src/app/services/user.service';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { Router } from '@angular/router';
import { AppToastService } from 'src/app/services/toastr.service';

@Component({
  selector: 'app-account',
  templateUrl: './account.component.html',
  styleUrls: ['./account.component.css']
})
export class AccountComponent implements OnInit {
  user;
  userId;
  accountForm: FormGroup;
  isSubmitted = false;

  constructor(
    private _userService: UserService,
    private _router: Router,
    private _toast: AppToastService,
    private fb: FormBuilder
  ) {}

  ngOnInit() {
    // Initiate the form
    this.accountForm = this.fb.group({
      phone: this.fb.group({
        home: [' ', Validators.minLength(10)],
        mobile: [' ', Validators.minLength(10)],
        extension: [' ', Validators.maxLength(5)]
      }),
      birthday: this.fb.group({
        month: '',
        day: ''
      })
    });

    // Get userId from localstorage, then fetch the details
    this.userId = this._userService.getUserIdFromLocalStorage();

    // Get user from userId
    this._userService.getUserAccountInfo(this.userId).subscribe(
      response => {
        this.user = response['user'];
        this.accountForm.patchValue(response['user']);
      },
      error => console.log(error['message'])
    );
  }

  // Access form controls
  get fControls() {
    return this.accountForm.controls;
  }

  updateUser() {
    // Check for form validity
    this.isSubmitted = true;
    if (this.accountForm.invalid) {
      return;
    }

    let updatedUser = this.accountForm.value;
    updatedUser.id = this.userId;

    console.log(updatedUser);

  }

1
  • 1
    use safe navigation operator everywhere (expect for model binding ) for example *ngIf="isSubmitted && fControls?.home?.errors" Commented Nov 11, 2019 at 6:30

1 Answer 1

2

use safe navigation operator ?. It checks whether the variable is null or undefined so that our template won't try to select a property of something falsy.

In your case use it in your template where you are trying to access property of a object using . operator , for example : *ngIf="isSubmitted && fControls?.home?.errors"

Note : you shouldn't be using the same with model binding [(ngModel)]="employee?.name" is wrong

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks Joel. I had used these operators in template driven forms but not reactive forms. Now the errors gone away. Oddly though, my validation ins't working. I have a minlength property on each number and if I bring try to submit 5 numbers (less than 10) then it submits correctly and and reports no issue. Wondering why that might be.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.