FormArray : Cannot find control with unspecified name attribute in angular6

I created a form using the reactive and presentation form. When I invoke the fields for the submission form, this gives me the error.

I created a form using the reactive and presentation form. When I invoke the fields for the submission form, this gives me the error.

this Erorr :

Cannot find control with unspecified name attribute
    addProductFG:FormGroup;
  cats:Category[];
  subCats:Category[];
  PD:Productdetail[];
  selectedCat:number;
  valueIngrident=new FormArray([]);
  public loading=false;

constructor(private fb:FormBuilder,private productService:ProductinfoService,private catService:CategoryService) { }

ngOnInit() {
this.loading=true;
this.InitialFrom();
this.GetMainCat();
}

public CreateValueFiled(PD:Productdetail[]){
PD.map(element => {
this.valueIngrident.push(
new FormGroup({
infoId:new FormControl(element.id),
value:new FormControl('')
})
)
});
}

public GetMainCat(){
this.catService.GetMainCat().subscribe(
res=>{
this.cats=res;
this.loading=false;
}
)
}

get ValueFormControl(){
return this.addProductFG.get('values') as FormArray;
}

public InitialFrom():FormGroup{

this.addProductFG=this.fb.group({
  productTitle:['',Validators.compose([Validators.required])],
  productName:['',Validators.compose([Validators.required])],
  color:['',Validators.compose([Validators.required])],
  productImageName:['',Validators.compose([Validators.required])],
  price:['',Validators.compose([Validators.required])],
  gurantyMonth:['',Validators.compose([Validators.required])],
  gurantyCompanyName:['',Validators.compose([Validators.required])],
  values:this.valueIngrident
})
return this.addProductFG;

}
public ChangeSubCat(id:number){
this.loading=true;
this.catService.GetSubCatByCatId(id).subscribe(
res=>{
this.subCats=res;
this.loading=false;
}
)
}

public ChangeFormByType(id:number){
this.loading=true;
this.productService.GetPCIBySubId(id).subscribe(
res=>{
this.PD=res,
this.CreateValueFiled(this.PD),
this.loading=false;
}
)
}

and in HTML :

       <div formArray="values">
<div *ngFor="let valueCtrl of ValueFormControl.controls; let i=index" [formGroupName]="i">
<div class="form-inline lbin">
<label>g </label>
<input formControlName="value" >
</div>
</div>
</div>

and And this is my sample code in stackblitz Demo

Whats the Problem ? How Can I Solve This problem ?

Angular 8 Forms - How to Validate Forms in Angular using Form Builders

Angular 8 Forms - How to Validate Forms in Angular using Form Builders

In this Angular 8 forms tutorial gives an overview of the form builder in Angular 8 and how to validate forms in Angular 8 using form builders

Forms controls and form groups in Angular

Form controls are basically classes that can hold both the data values and the validation information of any form element, which means to say every form input you have in a reactive form should be bound by a form control. They are the basic units that make up reactive forms.

Form groups are constructs that basically wrap a collection of form controls. Just as the control gives you access to the state of an element, the group gives the same access, but to the state of the wrapped controls. Every single form control in the form group is identified by name when initializing.

Generating form controls

Setting up form controls, especially for very long forms, can quickly become both monotonous and stressful. Angular provides a helper service to solve this problem so that you can always obey the DRY concept of avoiding repetition. This service is called the form builder service.

Before we start…

To be able to follow through this article’s demonstration, you should have:

  • Node version 11.0 installed on your machine
  • Node Package Manager version 6.7 (usually ships with the Node installation)
  • Angular CLI version 8.0
  • The latest version of Angular (version 8)
// run the command in a terminal
ng version

Confirm that you are using version 8, and update to 8 if you are not.

  • Download this tutorial’s starter project here to follow through the demonstrations.
  • Unzip the project and initialize the Node modules in your terminal with this command:
npm install

Other things that would be nice to have are:

  • A working knowledge of the Angular framework at a beginner level
  • Familiarity with form controls in Angular will be a plus but not a requirement
Demo

In this tutorial, you will be taken through a code-along journey building a reactive form with the form builder. If you have followed this post from the start, you will have downloaded and opened the starter project in VS Code. If you open the employee.component.ts, file it should look like this:

import { Component, OnInit } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms'
@Component({
  selector: 'app-employee',
  templateUrl: './employee.component.html',
  styleUrls: ['./employee.component.css']
})
export class EmployeeComponent implements OnInit {
  bioSection = new FormGroup({
    firstName: new FormControl(''),
    lastName: new FormControl(''),
    age: new FormControl(''),
    stackDetails: new FormGroup({
      stack: new FormControl(''),
      experience: new FormControl('')
    }),
    address: new FormGroup({
        country: new FormControl(''),
        city: new FormControl('')
    })
  });
constructor() { }
ngOnInit() {
  }
  callingFunction() {
    console.log(this.bioSection.value);
   }
}

You can see that every single form control — and even the form group that partitions it — is spelled out, so over time, you as the developer keep repeating yourself. The form builder helps to solve this efficiency problem. To use the form builder, you must first register it.

Registering the form builder

To register the form builder in a component, the first thing to do is import it from Angular forms:

import { FormBuilder } from ‘@angular/forms’;

The next step is to inject the form builder service, which is an injectable provider that comes with the reactive forms module. You can then use the form builder after injecting it. Navigate to the employee.component.ts file and copy in the code block below:

import { Component, OnInit } from '@angular/core';
import { FormBuilder } from '@angular/forms'
@Component({
  selector: 'app-employee',
  templateUrl: './employee.component.html',
  styleUrls: ['./employee.component.css']
})
export class EmployeeComponent implements OnInit {
  bioSection = this.fb.group({
    firstName: [''],
    lastName: [''],
    age: [''],
    stackDetails: this.fb.group({
      stack: [''],
      experience: ['']
    }),
    address: this.fb.group({
        country: [''],
        city: ['']
    })
  });
constructor(private fb: FormBuilder) { }
ngOnInit() {
  }
  callingFunction() {
    console.log(this.bioSection.value);
   }
}

This does exactly the same thing as the previous code block you saw at the start, but you can see there is a lot less code and more structure — and, thus, optimal usage of resources. Form builders not only help to make your reactive forms’ code efficient, but they are also important for form validation.

Form validation

Using reactive forms in Angular, you can validate your forms inside the form builders. Run your application in development with the command:

ng serve

You will discover that the form submits even when you do not input values into the text boxes. This can easily be checked with form validators in reactive forms. The first thing to do, as with all elements of reactive forms, is to import it from Angular forms.

import { Validators } from '@angular/forms';

You can now play around with the validators by specifying the form controls that must be filled in order for the submit button to be active. Copy the code block below into the employee.component.ts file:

The last thing to do is to make sure the submit button’s active settings are set accordingly. Navigate to the employee.component.html file and make sure the submit statement looks like this:

<button type=”submit” [disabled]=”!bioSection.valid”>Submit Application</button>

If you run your application now, you will see that if you do not set an input for first name, you cannot submit the form — isn’t that cool? There are many more cool form validation tips you can get from the official guide here.

Displaying input values and status

The last thing you should know is how to use the value and status properties to display, in real time, the input values of your reactive form and whether it can be submitted or not.

The reactive forms API lets you use the value and status properties on your form group or form controls in the template section. Open your employee.component.html file and copy in the code block below:

<form [formGroup]="bioSection" (ngSubmit)="callingFunction()">
    <h3>Bio Details
</h3>

  <label>
    First Name:
    <input type="text" formControlName="firstName">
  </label> <br>
<label>
    Last Name:
    <input type="text" formControlName="lastName">
  </label> <br>
<label>
    Age:
    <input type="text" formControlName="age">
  </label>
<div formGroupName="stackDetails">
    <h3>Stack Details</h3>

    <label>
      Stack:
      <input type="text" formControlName="stack">
    </label> <br>

    <label>
      Experience:
      <input type="text" formControlName="experience">
    </label>
  </div>
<div formGroupName="address">
    <h3>Address</h3>

    <label>
      Country:
      <input type="text" formControlName="country">
    </label> <br>

    <label>
      City:
      <input type="text" formControlName="city">
    </label>
  </div>
<button type="submit" [disabled]="!bioSection.valid">Submit Application</button>
  <p>
    Real-time data: {{ bioSection.value | json }}
  </p>
  <p>
    Your form status is : {{ bioSection.status }}
  </p>
</form>

This displays both the value and the status for submission for you in the interface as you use the form. The complete code to this tutorial can be found here on GitHub.

Conclusion

This article gives an overview of the form builder and how it is a great efficiency enabler for form controls and form groups. It also shows how important it can be for handling form validation easily with reactive forms. Happy hacking!

Manage reactive form controls with form groups in Angular 8

Manage reactive form controls with form groups in Angular 8

We explain how you can divide form controls by form groups in Angular 8, providing a platform to easily access the template element as groups.

Why are reactive forms important?

With reactive forms, you will discover that it is easier to build cleaner forms. Because every JavaScript framework advises that you don’t make the template clustered, this has become a priority as the form logic now lies in the component class.

It also reduces the need to use a lot of directives and even end-to-end testing since you can now easily test your forms. It gives the developer all the control, and nothing is implicit anymore — every choice about inputs and controls must be made intentionally and, of course, explicitly.

In Angular, form controls are classes that can hold both the data values and the validation information of any form element. That is to say, every form input you have in a reactive form should be bound by a form control.

These are the basic units that make up reactive forms. In this article, you will be shown how form controls can be divided by form groups to create clusters to provide a platform to easily access the template element as groups.

What is a form group?

Form groups wrap a collection of form controls; just as the control gives you access to the state of an element, the group gives the same access but to the state of the wrapped controls. Every single form control in the form group is identified by name when initializing.

A FormGroup aggregates the values of each child FormControl into one object, with each control name as the key. It calculates its status by reducing the status values of its children.

Before you start…

To be able to follow through this article’s demonstration, you should have:

// run the command in a terminal
ng version

Confirm that you are using version 8, and update to 8 if you are not.

  • Download the Augury Chrome extension here.
  • Download this tutorial’s starter project here to follow through the demonstrations.
  • Unzip the project and initialize the Node modules in your terminal with this command:
npm install

Other things that would be nice to have are:

  • A working knowledge of the Angular framework at a beginner level
  • Familiarity with form controls in Angular will be a plus but not a requirement
Demo

To illustrate the concept of form groups, we will go through the process of building a reactive form so that you can fully grasp how to set it up with form groups. From here, we assume you have downloaded the starter project on GitHub and opened it in VS Code.

Registering form groups

The first thing to do is to tell Angular that you want to make use of the form group by importing it inside the appropriate component. Navigate to the employee.component.ts file and copy in the code block below:

import { Component, OnInit } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms'
@Component({
  selector: 'app-employee',
  templateUrl: './employee.component.html',
  styleUrls: ['./employee.component.css']
})
export class EmployeeComponent implements OnInit {
  bioSection = new FormGroup({
    firstName: new FormControl(''),
    lastName: new FormControl(''),
    age: new FormControl('')
  });
constructor() { }
ngOnInit() {
  }
}

Here the form group was both imported and initialized to group together some form controls that compose the bio section of the form. To reflect this group, you have to associate the model to the view with the form group name, like this:

// copy inside the employee.component.html file
<form [formGroup]="bioSection" (ngSubmit)="callingFunction()">

<label>
First Name:
<input type="text" formControlName="firstName">
</label>
<label>
Last Name:
<input type="text" formControlName="lastName">
</label>
<label>
Age:
<input type="text" formControlName="age">
</label>
<button type="submit">Submit Application</button>
</form>

Just like the form control, the form group name is used to identify the form group in the view, and on submit, the callingFunction will be triggered. Your app.component.html file should look like this:

<div style="text-align:center">
<h2>Angular Job Board </h2>
<app-employee></app-employee>
</div>

Now run your application in development with the command:

ng serve

It should look like this:


Nesting form groups

Yes, the reactive forms API makes it possible to nest a form group inside another form group. Copy the code block below into the employee.component.ts file:

import { Component, OnInit } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms'
@Component({
selector: 'app-employee',
templateUrl: './employee.component.html',
styleUrls: ['./employee.component.css']
})
export class EmployeeComponent implements OnInit {
bioSection = new FormGroup({
firstName: new FormControl(''),
lastName: new FormControl(''),
age: new FormControl(''),
stackDetails: new FormGroup({
stack: new FormControl(''),
experience: new FormControl('')
}),
address: new FormGroup({
country: new FormControl(''),
city: new FormControl('')
})
});
constructor() { }
ngOnInit() {
}
callingFunction() {
console.log(this.bioSection.value);
}
}

Here you see that the main form group wrapper is the bio section inside which both the stack details group and the address group is nested. It is important to note — as you see in the code block — that nested form groups are not defined by the assignment statement, but rather with the colon, just like you will a form control. Reflecting this in the view will look like this:

// copy inside the employee.component.html file
<form [formGroup]="bioSection" (ngSubmit)="callingFunction()">
<h3>Bio Details
</h3>

<label>
First Name:
<input type="text" formControlName="firstName">
</label> <br>
<label>
Last Name:
<input type="text" formControlName="lastName">
</label> <br>
<label>
Age:
<input type="text" formControlName="age">
</label>
<div formGroupName="stackDetails">
<h3>Stack Details</h3>

&lt;label&gt;
  Stack:
  &lt;input type="text" formControlName="stack"&gt;
&lt;/label&gt; &lt;br&gt;

&lt;label&gt;
  Experience:
  &lt;input type="text" formControlName="experience"&gt;
&lt;/label&gt;

</div>
<div formGroupName="address">
<h3>Address</h3>

&lt;label&gt;
  Country:
  &lt;input type="text" formControlName="country"&gt;
&lt;/label&gt; &lt;br&gt;

&lt;label&gt;
  City:
  &lt;input type="text" formControlName="city"&gt;
&lt;/label&gt;

</div>
<button type="submit">Submit Application</button>
</form>

It is very important that every name in the model and the view match — you do not misspell the form control names! When you save and run the application, if you do get any errors, read the error message and correct the misspelling you must have used. You can style your component with the style instructions below:

input[type=text] {
width: 30%;
padding: 8px 14px;
margin: 2px;
box-sizing: border-box;
}
button {
font-size: 12px;
margin: 2px;
padding: 8px 14px;
}

If you run the application, you should see something like this in your browser:



When you use the form and submit, you will see your input results returned in the browser console. The complete code to this tutorial can be found here on GitHub.

Conclusion

In addition to learning about form controls, you have now been introduced to the important concept of grouping these controls. You were also shown why grouping them is very important, as it ensures that their collective instances can be captured at once. The next concept we will be looking at is form builders.

Thanks for reading. If you liked this post, share it with all of your programming buddies!

Further reading

☞ Best 50 Angular Interview Questions for Frontend Developers in 2019

To become an Outstanding AngularJs Developer - part 2

To become an Outstanding AngularJs Developer - part 1

To become an effective Angular developer, you need to learn 19 things in this article

Top 18 Mistakes AngularJS Developers Makes

AngularJS Directive with Example: ng-init, ng-app, ng-repeat, ng-model

☞ Angular 8 (formerly Angular 2) - The Complete Guide


Originally published on blog.logrocket.com