Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 6 Nested FormGroup Template Validation

My form group structure looks like this (order.component.ts):

this.orderForm = this.formBuilder.group({
  customer: this.formBuilder.group({
    name: ['', Validators.required],
    phone: ['', Validators.required],
    email: ['', Validators.required]
  }),
  ...
});

In the template (order.component.html) I have:

<form [formGroup]="orderForm" (ngSubmit)="onSubmit()">
  <fieldset formGroupName="customer">
    <legend>Customer Information</legend>
    <label for="name">Full name:</label>
    <input type="text" formControlName="name" class="form-control" name="name" id="name" required>
    <small class="form-text text-danger" *ngIf="orderForm.controls['customer'].controls['name'].invalid && (orderForm.controls['customer'].controls['name'].dirty || orderForm.controls['customer'].controls['name'].touched)">Name invalid</small>
  </fieldset>
  ...
</form>

This works, but is a shorter way of expressing orderForm.controls['customer'].controls['name']? For example it would be more succinct for the *ngIf condition to be "name.invalid && (name.dirty || name.touched)"

like image 794
Alex Mohr Avatar asked Jul 21 '18 19:07

Alex Mohr


People also ask

How to setup form validation in Angular 6 using template-driven forms?

This is a quick example of how to setup form validation in Angular 6 using Template-Driven Forms. The example is a simple registration form with pretty standard fields for first name, last name, email and password. All fields are required, plus the email field must be a valid email address and the password field must have a min length of 6.

How do you validate form input fields in angular?

The form input fields use the [ (ngModel)] directive to bind to properties of the model object in the app component. Validation is implemented using the attributes required, minlength and email, the Angular framework contains directives that match these attributes with built-in validator functions.

What are the built-in validators in angular?

The Angular comes up with several built-in validators for this purpose. They are minlength, maxlength, email, pattern, required, etc.

How to get the control of a nested form group?

One way i use alot is to cast the sub formGroup into a form group as the 'get ()' method returns an abstractControl and use the 'get ()' method to extract the control of the nested formGroup like so :


2 Answers

I ran into same issue. My main problem was that ng build --prod fails when using orderForm.controls['customer'].controls['name'] with error:

Property 'controls' does not exist on type 'AbstractControl'.

Apparently this is just type issue when template gets compiled to TS.

My approach is to create getter for nested form group and cast the correct type which solves both my issue and yours:

get customer() {
  return this.orderForm.controls.customer as FormGroup;
}

used in HTML:

<small class="form-text text-danger" *ngIf="customer.controls['name'].invalid && (customer.controls['name'].dirty || customer.controls['name'].touched)">Name invalid</small>
like image 138
Martin Nuc Avatar answered Sep 23 '22 19:09

Martin Nuc


Yes, that is the correct way to fetch nested form Control and no shortcut.

or you could create some property in your component which points to orderForm.get('customer') form object

private customerForm : FormGroup

And assign it after form initialization

this.customerForm = this.orderForm.get('customer')

and fetch it like {{customerForm.get('name').valid}}

like image 34
Amit Chigadani Avatar answered Sep 24 '22 19:09

Amit Chigadani