Angular FormArray display validation errors

angular formarray custom validation
angular formarray validation stackblitz
ngfor formarray
get formgroup from formarray
loop through formarray
formarray valuechanges
there are no form controls registered with this array yet
formarray of formgroups

I have Angular form that is built with help of FormBuilder.

Form contains a FormArray which has as many fields as user wants. I've set validator for fields

this.fb.array([this.fb.control('', Validators.required)])

and for each new push validator is the same.

The problem is that I don't know how to access a specific field's isValid property since they are bound with FormControl via [formControlName]="index".

I've tried to do it that way, but it doesn't seem to work

<div *ngIf="array.at(index).invalid" class="alert alert-danger p-2">
</div>

Where array is a formArray.controls passed from a parent.

Update #1

There is a case https://stackblitz.com/edit/angular-7ppkoh

I don't really think this would be possible completely on the template. That's because to access the FormArray's control's state in your template, you'll have to access this.formGroup.get('features').controls[i].invalid. But since get returns an instance of type AbstractControl, you won't have access to the controls array on it. For that, you'll have to typecast whatever is returned from this.formGroup.get('features') into a FormArray. And I don't really think that would be possible on the template.

You'll have to create a method in your class that would return the validity of the control based on the index.

So if we continue to refer to your stackblitz eg, here's how:

<form [formGroup]="formGroup">
  <div formArrayName="features">
    <div 
      class="row no-gutters form-group" 
      *ngFor="let feature of features.controls; let index = index; let last = last">
      <input 
        type="text" 
        class="form-control px-2 col" 
        [formControlName]="index" 
        title="feature" 
        required>

        IS Invalid - {{ getValidity(index) }}

      <div class="col-3 col-md-2 row no-gutters">
        <button 
          class="col btn btn-outline-danger" 
          (click)="removeFeature(index)">
          -
        </button>
        <button 
          class="col btn btn-success" 
          *ngIf="last" 
          (click)="addFeature()">
          +
        </button>
      </div>
    </div>
  </div>
</form>

And in your class:

import { Component } from '@angular/core';
import { FormArray, FormBuilder, FormControl, Validators } from '@angular/forms';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {

  constructor(
    private fb: FormBuilder,
  ) {}

  formGroup = this.fb.group({
    features: this.fb.array([this.fb.control('', Validators.required)])
  });

  get features(): FormArray {
    return this.formGroup.get('features') as FormArray;
  }

  addFeature(): void {
    this.features.push(this.fb.control('', Validators.required));
  }

  getValidity(i) {
    return (<FormArray>this.formGroup.get('features')).controls[i].invalid;
  }

  removeFeature(index): void {
    this.features.removeAt(index);
    console.log(this.features);
  }

}
UPDATE

A few months back I realized that calling a method in one of the data-binding syntaxes(i.e. String Interpolation - {{ ... }}, Property Binding - [propertyName]="methodName()", or Attribute Binding - [class.class-name]="methodName()" OR [style.styleName]="methodName()") is extremely costly as far as performance is concerned.

So, you should do it using:

{{ formGroup.controls['features'].controls[index].invalid }}

Instead of:

{{ getValidity(index) }}

Here's an Updated Working Sample StackBlitz for your ref.

Angular FormArray Validation, In this video we will discuss validating FormArray in Angular. Text version of the video Duration: 4:56 Posted: Nov 13, 2018 I have Angular form that is built with help of FormBuilder. Form contains a FormArray which has as many fields as user wants. I&#8217;ve set validator for fields this.fb.array([this.fb.control('', Validators.required)]) and for each new push validator is the same. The problem is that I don&#8217;t know how to access a specific field&#8217;s isValid property since they are bound with

In the ngFor statement, you are defining the variable "feature" to use for each control of the form array.

*ngFor="let feature of features.controls; let index = index; let last = last"

You can use that variable to get the invalid status of that control.

feature.invalid 

Here is the Stackblitz


Additionally

You don't need the required attribute in the HTML when you are using reactive forms.

So this

<input type="text" class="form-control px-2 col" [formControlName]="index" title="feature" required>

Can be

<input type="text" class="form-control px-2 col" [formControlName]="index" title="feature">

Angular formarray validation, I have Angular form that is built with help of FormBuilder. Form contains a FormArray which has as many fields as user wants. I've set validator for fields  Display Server Side Validation Errors with Angular Input Validation is a big topic when it comes to forms. And even more in those large, enterprisey apps, where validation can become really crazy. Now, Angular forms of course provide different mechanisms for handling validation out of the box.

The FormGroup class has a get method which returns the abstractControl for the given key. The one you use in formControlName.

Here the links for both Api docs: AbstractControl FormGroup

<form [formGroup]="form">
  <input formControlName="name" type="text" />
  <div *ngIf="form.get('name').invalid">
    <p><Message you like to show/p>
  </div>
</form>

Angular FormArray display validation errors - angular - html, disable(opts: { onlySelf?: boolean; emitEvent?: boolean; } = {}): void enable(​opts: { onlySelf?: A FormArray aggregates the values of each child FormControl into an array. A synchronous validator function, or an array of such functions, or an This method performs strict checks, and throws an error if you try to set the  In this article, we’re going to learn how to develop a generic method that displays validation errors in Angular’s form. I will walk you through the process and ideas behind the decisions I made along the way. As always, to get a taste of what I’m talking about, let’s first take a look at a nice visualization of the final result:

You Should use form controls to achieve that sharply.

<div *ngIf="formGroup.get('features').controls[i].controls.index.invalid && (formGroup.get('features').controls[i].controls.index.dirty || formGroup.get('features').controls[i].controls.index.touched)"                                          class="text-center error">
<p [hidden]="!formGroup.get('features').controls[i].controls.index.errors.required">Index is required.</p>
</div>

FormArray, With validator directives, working with Angular 4 forms is easy. markAsTouched​() is used to make the form touched so we can display the errors at that moment. The key types used here are FormGroup, FormControl and FormArray. Angular reactive forms are great. Dinamicity, validation and binding make me - and part of the community with me - prefer them over template driven ones. At the end of the day, however, either being reactive or template driven, a form should let an application collect data from the users and provide.

As above answer using

feature.invalid from features.controls

let you validate all elements inside that controlat once.

However if you want to validate a specific element can you following code:

> feature.controls.controlname.invalid

Note: I'm using feature not features

Angular 4 Forms: Nesting and Input Validation, dynamically display controls in FormArray using Angular 5 Reactive Forms and remove required field validator based on checkbox selection to display an error indicator by using Cascading Style Sheets (CSS) selector. FormArray Validation using FormGroup Suppose FormArray contains the array of FormGroup and each FormGroup contains FormControl with some validators. FormArray will be considered validated only if all the FormGroup are validated and FormGroup will be validated only if all the FormControl are validated. Find the code snippet.

Angular 5, This is a complex angular 8 reactive forms guide with the example on stackblitz.​com. rows with form array; How to use currency pipe in HTML and in component input field error --><mat-error *ngIf="exampleForm.controls. Of course, you could separate it to another screen or use modals or any other  Control Validation. By default, whenever a value of a FormControl changes, Angular runs the control validation process. For example, if you have an input that is bound to a form control, Angular performs the control validation process for every keystroke.

Angular 8, reactive forms with dynamic rows, validation and value , In this article, I'd like to discuss this peculiar creation — a FormArray, Moreover, we'll see how we can apply custom validation to it. Let's say we need to display a form where users can add, edit, or remove from a list of skills: valid ; Otherwise, it returns an object which indicates the nature of the error. Every time the value of a form control changes, Angular runs validation and generates either a list of validation errors, which results in an INVALID status, or null, which results in a VALID status. You can then inspect the control's state by exporting ngModel to a local template variable.

Angular Reactive Forms: The Ultimate Guide to FormArray, Create Nested Form using Angular's FormArray API with Reactive Forms; Create Confirm Password Validation using Custom Validator with Angular 7; Full Angular 7 Reactive Form and Form firstName.errors}"> First name</label> <​input type="text" class="form-control" Following will be the final output:. NOTE: The content is relevant to Angular Material 2+. The title says Angular Material 7, since it’s the latest version out, and it’s intended to attract attention (we always want to read up-to-date information). It seems like a basic necessity to be able to validate a form by data which is currently in the form.

Comments
  • Please consider creating a stackblitz.
  • @SiddharthAjmera check it out
  • Thank you. I did it that way get featureControl() { return (this.group.get('features') as FormArray).controls[this.index]; } and that worked!
  • How do you intend of passing this.index in the template though? Just curious.
  • I've shown you an adapted version of what I have. Actually, features is an extra component which consumes index from parent. So there won't be any problems with index
  • Oh. Right. Perfect!
  • Can you elaborate or provide some documentation on the performance penalties of calling a method with data-binding?