> ## app.component.ts ##
When click on SAve Button, I get error, ERROR TypeError: Cannot read property 'value' of undefined
When passing addRow(name.value) in second row it worked fine. But, when I pass it is first row as saveRow(name.value).!!! ERROR TypeError: Cannot read property 'value' of undefined.....................I also tried saveRow(name) than error doesnot come but value passed is undefined!
<div class="container">
<div class="row">
<form [formGroup]="form1">
<div class="form-group">
<table class="table">
<thead>
<tr>
<td>S.No</td>
<td>NAME</td>
<td>WEIGHT(in grams)</td>
<td>QUANTITY</td>
</tr>
</thead>
<tbody>
<tr *ngFor="let i of form1.get('id').value; let k = index">
<td>
<ng-container *ngIf="tempindex !== k">{{ form1.get('id').value[k] }}</ng-container>
</td>
<td>
<ng-container *ngIf="tempindex !== k">{{ form1.get('name').value[k] }}</ng-container>
<input type="text" *ngIf="tempindex === k" [value]="form1.get('name').value[k]" #name>
</td>
<td>
<ng-container *ngIf="tempindex !== k">{{ form1.get('weight').value[k] }}</ng-container>
<input type="text" *ngIf="tempindex === k" [value]="form1.get('name').value[k]" #weight>
</td>
<td>
<ng-container *ngIf="tempindex !== k">{{ form1.get('quantity').value[k] }}</ng-container>
<input type="text" *ngIf="tempindex === k" [value]="form1.get('quantity').value[k]" #quantity>
</td>
<td>
<ng-container *ngIf="tempindex === k">
<button *ngIf="editclicked" class="btn btn-primary" (click)="saveRow(k, name.value, weight.value, quantity.value)">Save</button>
</ng-container>
<button *ngIf="!editclicked" class="btn btn-primary" (click)="editRow(k)">Edit</button>
<button *ngIf="!editclicked" class="btn btn-danger" (click)="delRow(k)">Delete</button>
</td>
</tr>
<button *ngIf="!addclicked" class="btn btn-default" (click)="addRow()">ADD</button>
<tr *ngIf="addclicked">
<td></td>
<td>
<input type="text" #name>
</td>
<td>
<input type="text" #weight>
</td>
<td>
<input type="text" #quantity>
</td>
<td><button class="btn btn-primary" (click)="hitadd(name.value, weight.value, quantity.value)">Add</button>
<button class="btn btn-danger" (click)="hitcancel()">Cancel</button>
</td>
</tr>
</tbody>
</table>
</div>
</form>
</div>
</div>
app.component.html
First tr is used to fetch all fields from FormArrays
Second tr is used to add new data to the FormArrays (Problem!!!)
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormControl, FormArray } from '@angular/forms'
import { element } from 'protractor';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
title = 'app';
form1: FormGroup;
addclicked = false;
tempId = '';
tempindex;
editclicked = false;
ngOnInit() {
this.form1 = new FormGroup({
'id': new FormArray([]),
'name': new FormArray([]),
'weight': new FormArray([]),
'quantity': new FormArray([])
// 'id': new FormArray([new FormControl('1'), new FormControl('2')]),
// 'name': new FormArray([new FormControl('Beans'), new FormControl('Soup')]),
// 'weight': new FormArray([new FormControl('100'), new FormControl('125')]),
// 'quantity': new FormArray([new FormControl('60'), new FormControl('20')])
});
}
addRow(){
this.addclicked = true;
this.tempId = '';
}
hitcancel(){
this.addclicked = false;
this.tempId = '';
}
hitadd(name, weight, quantity){
this.tempId = (this.ids.value.length + 1).toString(10);
this.ids.push(new FormControl(this.tempId));
this.names.push(new FormControl(name));
this.weights.push(new FormControl(weight));
this.quantities.push(new FormControl(quantity));
this.tempId = '';
this.addclicked = false;
}
editRow(index: number){
this.editclicked = true;
this.tempindex = index;
//this.ids.at(index).patchValue(null);
}
saveRow(index, name, weight, quantity){
this.editclicked = false;
this.tempindex = undefined;
console.log(name);
// console.log(this.names.at(index).setValue(name));
// this.weights.at(index).setValue(weight);
// this.quantities.at(index).setValue(quantity);
}
delRow(index: number){
this.addclicked = false;
this.ids.removeAt(index);
this.names.removeAt(index);
this.weights.removeAt(index);
this.quantities.removeAt(index);
let i = 0;
this.ids.controls.forEach(element => {
i++;
element.setValue(i.toString(10))
});
}
get ids(){
return this.form1.get('id') as FormArray;
}
get names(){
return this.form1.get('name') as FormArray;
}
get weights(){
return this.form1.get('weight') as FormArray;
}
get quantities(){
return this.form1.get('quantity') as FormArray;
}
}
<!-- end snippet -->
I have updated the above code but emitting non-important element according to my prospective. Please take a look.
These are the modifications:
app.component.ts
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormControl, FormArray } from '@angular/forms'
import { element } from 'protractor';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
title = 'app';
form1: FormGroup;
addclicked = false;
tempId = '';
ngOnInit() {
this.form1 = new FormGroup({
'id': new FormArray([]),
'name': new FormArray([]),
'weight': new FormArray([]),
'quantity': new FormArray([])
// 'id': new FormArray([new FormControl('1'), new FormControl('2')]),
// 'name': new FormArray([new FormControl('Beans'), new FormControl('Soup')]),
// 'weight': new FormArray([new FormControl('100'), new FormControl('125')]),
// 'quantity': new FormArray([new FormControl('60'), new FormControl('20')])
});
}
addRow(){
this.addclicked = true;
this.tempId = '';
}
hitcancel(){
this.addclicked = false;
this.tempId = '';
}
hitadd(name, weight, quantity){
this.tempId = (this.ids.value.length + 1).toString(10);
this.ids.push(new FormControl(this.tempId));
this.names.push(new FormControl(name));
this.weights.push(new FormControl(weight));
this.quantities.push(new FormControl(quantity));
this.tempId = '';
this.addclicked = false;
}
editRow(index: number){
}
delRow(index: number){
this.ids.removeAt(index);
this.names.removeAt(index);
this.weights.removeAt(index);
this.quantities.removeAt(index);
let i = 0;
this.ids.controls.forEach(element => {
i++;
element.setValue(i.toString(10))
});
}
get ids(){
return this.form1.get('id') as FormArray;
}
get names(){
return this.form1.get('name') as FormArray;
}
get weights(){
return this.form1.get('weight') as FormArray;
}
get quantities(){
return this.form1.get('quantity') as FormArray;
}
}
app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
ReactiveFormsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
app.component.html
<div class="container">
<div class="row">
<form [formGroup]="form1">
<div class="form-group">
<table class="table">
<thead>
<tr>
<td>S.No</td>
<td>NAME</td>
<td>WEIGHT(in grams)</td>
<td>QUANTITY</td>
</tr>
</thead>
<tbody>
<tr *ngFor="let i of form1.get('id').value; let k = index">
<td>{{ form1.get('id').value[k] }}</td>
<td>{{ form1.get('name').value[k] }}</td>
<td>{{ form1.get('weight').value[k] }}</td>
<td>{{ form1.get('quantity').value[k] }}</td>
<td><button class="btn btn-primary" (click)="editRow(k)">Edit</button> <button class="btn btn-danger"
(click)="delRow(k)">Delete</button></td>
</tr>
<button *ngIf="!addclicked" class="btn btn-default" (click)="addRow()">ADD</button>
<tr *ngIf="addclicked">
<td></td>
<td>
<input type="text" #name>
</td>
<td>
<input type="text" #weight>
</td>
<td>
<input type="text" #quantity>
</td>
<td><button class="btn btn-primary" (click)="hitadd(name.value, weight.value, quantity.value)">Add</button>
<button
class="btn btn-danger" (click)="hitcancel()">Cancel</button>
</td>
</tr>
</tbody>
</table>
</div>
</form>
</div>
In light of the code modifications that you have undergone, try to see if this fixes the error you are getting,
<td>
<ng-container *ngIf="tempindex !== k">{{ form1.get('id').value[k] }}</ng-container>
</td>
<td>
<ng-container *ngIf="tempindex !== k">{{ form1.get('name').value[k]}}</ng-container>
<input type="text" *ngIf="tempindex === k" [value]="form1.get('name').value[k]" #nameEdit>
</td>
<td>
<ng-container *ngIf="tempindex !== k">{{ form1.get('weight').value[k] }}</ng-container>
<input type="text" *ngIf="tempindex === k" [value]="form1.get('name').value[k]" #weightEdit>
</td>
<td>
<ng-container *ngIf="tempindex !== k">{{ form1.get('quantity').value[k] }}</ng-container>
<input type="text" *ngIf="tempindex === k" [value]="form1.get('quantity').value[k]" #quantityEdit>
</td>
<td>
<ng-container *ngIf="tempindex === k">
<button *ngIf="editclicked" class="btn btn-primary" (click)="saveRow(k, nameEdit.value, weightEdit.value, quantityEdit.value)">Save</button>
</ng-container>
<button *ngIf="!editclicked" class="btn btn-primary" (click)="editRow(k)">Edit</button>
<button *ngIf="!editclicked" class="btn btn-danger" (click)="delRow(k)">Delete</button>
</td>
In your component,
saveRow(index: number, name, weight, quantity){
this.names.at(index).setValue(name));
this.weights.at(index).setValue(weight);
this.quantities.at(index).setValue(quantity);
this.editclicked = false;
this.tempindex = undefined;
}
module
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { ReactiveFormsModule, FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
ReactiveFormsModule,
FormsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
template
<div class="container">
<div class="row">
<form [formGroup]="form1">
<div class="form-group">
<table class="table">
<thead>
<tr>
<td>S.No</td>
<td>NAME</td>
<td>WEIGHT(in grams)</td>
<td>QUANTITY</td>
</tr>
</thead>
<tbody>
<tr *ngFor="let i of form1.get('id').value; let k = index">
<td>
<ng-container *ngIf="tempindex !== k">{{ form1.get('id').value[k] }}</ng-container>
</td>
<td>
<ng-container *ngIf="tempindex !== k">{{ form1.get('name').value[k]}}</ng-container>
<input type="text" *ngIf="tempindex === k" [(ngModel)]="tempName" [ngModelOptions]="{standalone: true}">
</td>
<td>
<ng-container *ngIf="tempindex !== k">{{ form1.get('weight').value[k] }}</ng-container>
<input type="text" *ngIf="tempindex === k" [(ngModel)]="tempWeight" [ngModelOptions]="{standalone: true}">
</td>
<td>
<ng-container *ngIf="tempindex !== k">{{ form1.get('quantity').value[k] }}</ng-container>
<input type="text" *ngIf="tempindex === k" [(ngModel)]="tempQuantity" [ngModelOptions]="{standalone: true}">
</td>
<td>
<ng-container *ngIf="tempindex === k">
<button *ngIf="editclicked" class="btn btn-primary" (click)="saveRow(k, tempName, tempWeight, tempQuantity)">Save</button>
</ng-container>
<button *ngIf="!editclicked" class="btn btn-primary" (click)="editRow(k)">Edit</button>
<button *ngIf="!editclicked" class="btn btn-danger" (click)="delRow(k)">Delete</button>
</td>
</tr>
<button *ngIf="!addclicked" class="btn btn-default" (click)="addRow()">ADD</button>
<tr *ngIf="addclicked">
<td></td>
<td>
<input type="text" #name>
</td>
<td>
<input type="text" #weight>
</td>
<td>
<input type="text" #quantity>
</td>
<td><button class="btn btn-primary" (click)="hitadd(name.value, weight.value, quantity.value)">Add</button>
<button class="btn btn-danger" (click)="hitcancel()">Cancel</button>
</td>
</tr>
</tbody>
</table>
</div>
</form>
</div>
</div>
component
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormControl, FormArray } from '@angular/forms'
import { element } from 'protractor';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
title = 'app';
form1: FormGroup;
addclicked = false;
tempId = '';
tempName = '';
tempWeight = '';
tempQuantity = '';
tempindex;
editclicked = false;
ngOnInit() {
this.form1 = new FormGroup({
'id': new FormArray([]),
'name': new FormArray([]),
'weight': new FormArray([]),
'quantity': new FormArray([])
// 'id': new FormArray([new FormControl('1'), new FormControl('2')]),
// 'name': new FormArray([new FormControl('Beans'), new FormControl('Soup')]),
// 'weight': new FormArray([new FormControl('100'), new FormControl('125')]),
// 'quantity': new FormArray([new FormControl('60'), new FormControl('20')])
});
}
addRow(){
this.addclicked = true;
this.tempId = '';
}
hitcancel(){
this.addclicked = false;
this.tempId = '';
}
hitadd(name, weight, quantity){
this.tempId = (this.ids.value.length + 1).toString(10);
this.ids.push(new FormControl(this.tempId));
this.names.push(new FormControl(name));
this.weights.push(new FormControl(weight));
this.quantities.push(new FormControl(quantity));
this.tempId = '';
this.addclicked = false;
console.log(this.form1);
}
editRow(index: number) {
this.tempName = this.names.value[index];
this.tempWeight = this.weights.value[index];
this.tempQuantity = this.quantities.value[index];
this.editclicked = true;
this.tempindex = index;
//this.ids.at(index).patchValue(null);
}
saveRow(index: number, name, weight, quantity){
this.names.at(index).setValue(name);
this.weights.at(index).setValue(weight);
this.quantities.at(index).setValue(quantity);
this.editclicked = false;
this.tempindex = undefined;
}
delRow(index: number){
this.addclicked = false;
this.ids.removeAt(index);
this.names.removeAt(index);
this.weights.removeAt(index);
this.quantities.removeAt(index);
let i = 0;
this.ids.controls.forEach(element => {
i++;
element.setValue(i.toString(10))
});
}
get ids(){
return this.form1.get('id') as FormArray;
}
get names(){
return this.form1.get('name') as FormArray;
}
get weights(){
return this.form1.get('weight') as FormArray;
}
get quantities(){
return this.form1.get('quantity') as FormArray;
}
}
This one works. Please remove unwanted contented from the code here if you like. Just showing it fully here for now.