'ERROR Error: Cannot find control with path: 'products -> Quantity'
When I add one product in my form, show this error. My code ts:
this.products = this.ps.getProduct();
this.addform = this.fb.group({
'invoice_number': new FormControl('', [Validators.required, Validators.nullValidator]),
'Subtotal': new FormControl('', Validators.required),
'products': this.fb.array([
]),
'total': new FormControl('', Validators.required),
});
Model class:
export class Sale {
invoice_number: number;
products: Products[];
}
My HTML code:
<form [formGroup]="addform" (ngSubmit)="onaddsale()">
<div class="contant">
<div class="row">
<div class="input-field col s4">
<input formControlName="invoice_number" id="invoice_number" type="text" class="validate">
</div>
</div>
</div>
<tr formArrayName="products" class="group" style="cursor: pointer" *ngFor="let item of products; index as i" [formGroupName]="i">
<td>
<input formControlName="Subtotal" [(ngModel)]="item.Subtotal" readonly type="number" />
</td>
<td>
<input formControlName="total" [(ngModel)]="item.total" readonly type="number" />
</td>
</tr>
</form>
In my HTML doesn't display nothing, also show my error in console.
Can you suggest what is the problem, how to solution this?
Solution 1:[1]
Try adding formGroupName like:
<form [formGroup]="addform" (ngSubmit)="onaddsale()">
<div class="contant">
<div class="row">
<div class="input-field col s4">
<input formControlName="invoice_number" id="invoice_number" type="text" class="validate">
</div>
</div>
</div>
<tr formArrayName="products" class="group" style="cursor: pointer" *ngFor="let item of products; index as i">
<div [formGroupName]="i">
<td>
<input formControlName="subtotal" readonly type="number" />
</td>
<td>
<input formControlName="total" readonly type="number" />
</td>
</div>
</tr>
</form>
Solution 2:[2]
More slow I think you have a service ps that have a method getProducts() some like
getProduct(id:any)
{
return this.httpClient.get("url/"+id);
}
the url/Id return you a json like, e.g.
'invoice_number':222152
'product':[
{item:'some',total:120,subtotal:130},
{item:'other',total:110,subtotal:140}
]
Well, you must subscribe in ngOnInit to the service and, when you get the data create a formGroup
ngOnInit()
{
this.ps.getProduct('123').subscribe((data:any)=>{
this.createform(data)
}
}
//see that createForm is a function that return a formGroup
//this formGorup have two fields, "invoice_number" and "products"
//products is an array. We use a function that return a array
//of controls and "products" is thif.fb.array(the array of controls)
createForm(data:any)
{
return this.fb.group({
invoice_number:[data? data.invoice_number:null,
[Validators.required, Validators.nullValidator]],
products:this.fb.array(this.getProducts(data? data.products:null)
})
}
//getProducts return an array of Controls -really an array of group controls-
getProducts(products:any)
{
let controls[]=[];
if (products)
{
products.forEach(x=>{
controls.push(
this.fb.group({
total:[x.total,Validators.required]
subtotal:[x.total,Validators.required]
}
);
}
}
return controls;
}
Then your html it's like
<form [formGroup]="addform" (ngSubmit)="onaddsale()">
<div class="contant">
<div class="row">
<div class="input-field col s4">
<input formControlName="invoice_number" id="invoice_number" type="text" class="validate">
</div>
</div>
</div>
<tr formArrayName="products" class="group" style="cursor: pointer" *ngFor="let item of products; index as i" [formGroupName]="i">
<td>
<input formControlName="subtotal" readonly type="number" />
</td>
<td>
<input formControlName="total" readonly type="number" />
</td>
</tr>
</form>
See that you can use this.addForm=this.createForm() and the Form have empty values. NOTA: I use "subtotal" (not "Subtotal") choose use lowercase or CamelCase to named the variables
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Todd |
Solution 2 | Eliseo |