How can display nested array data in form array in angular2? - json

I have implemented FormGroup in angular2 project to render form and i have used formArray for getting nested array data
form.component.html
<div class="col-md-12" formArrayName="social_profiles">
<div *ngFor="let social of resumeForm.controls.social_profiles.controls; let i=index" class="panel panel-default m-t-10">
<div class="panel-heading" style="min-height: 30px;">
<span class="glyphicon glyphicon-remove pull-right" *ngIf="resumeForm.controls.social_profiles.controls.length > 1" (click)="removeSocialProfiles(i)"></span>
</div>
<div class="panel-body" [formGroupName]="i">
<social-profile [group]="resumeForm.controls.social_profiles.controls[i]"></social-profile>
</div>
</div>
</div>
form.component.ts
export class FormComponent implements OnInit {
public resumeForm: FormGroup;
constructor(private formBuilder: FormBuilder) {}
ngOnInit() {
this.resumeForm = this.formBuilder.group({
name: ['', Validators.required],
label: ['',],
email: [''],
phone: [''],
social_profiles: this.formBuilder.array([])
});
this.addSocialProfiles();
}
initSocialProfiles() {
return this.formBuilder.group({
network: [''],
url: ['']
});
}
addSocialProfiles() {
const control = <FormArray>this.resumeForm.controls['social_profiles'];
const addrCtrl = this.initSocialProfiles();
control.push(addrCtrl);
}
removeSocialProfiles(i: number) {
const control = <FormArray>this.resumeForm.controls['social_profiles'];
control.removeAt(i);
}
}
Where social-profile is child form for array
social-profile.component.html
<div [formGroup]="socialForm">
<div class="col-md-6">
<input type="text" class="form-control" placeholder="Enter Network" formControlName="network">
</div>
<div class="col-md-6">
<input type="text" class="form-control" placeholder="Enter Network URL" formControlName="url">
</div>
</div>
social-profile.component.ts
export class SocialProfileComponent {
#Input('group')
public socialForm: FormGroup;
}
Get JSON from Service callback
{
"basics_info": {
"name": "Joh Doe",
"label": "Programmer",
"Social_profiles": [{
"network": "Twitter",
"url": "https://www.twitter.com/kumarrishikesh12"
}, {
"network": "Facebook",
"url": "https://www.facebook.com/kumarrishikesh12"
}]
}
}
Add data Form working perfect but how can i display existing nested array of json (which is get from api) in form on edit time on page init ? Like below image

Here let's assume you have extracted the content from the object basics_info, i.e:
and assigned the JSON to a variable data, so that you end up with this content of data:
{
"name": "Joh Doe",
"label": "Programmer",
"Social_profiles": [{
"network": "Twitter",
"url": "https://www.twitter.com/kumarrishikesh12"
}, {
"network": "Facebook",
"url": "https://www.facebook.com/kumarrishikesh12"
}]
}
Then let's patch the values. You can patch the values after you have received the JSON (or build the form) after receiving data. Here I patch values after form has been built.
Below I like for clarification call another method inside patchValues, which actually sets the values.
patchValues() {
const control = <FormArray>this.resumeForm.controls['social_profiles'];
this.data.Social_profiles.forEach(x => { // iterate the array
control.push(this.patch(x.network, x.url)) // push values
});
}
patch(network, url) {
return this.fb.group({
network: [network],
url: [url]
});
}
The child should catch these changes just fine. Here's a demo for you, the variables are different, since I used an existing form I had. But the logic is absolutely the same.
Plunker

Related

Cannot read property 'setRowData' of undefined / Issue with HTML template?

Am maintaining an AG-GRID re-usable template with all necessary methods (clear filer/ CSV download/ Autofit..etc options) --- Base Template.
I have another AG-Grid template , which uses "Base Template" (thru dependency injection) and populate grid with a row of data based on searchString value. (Sample file below)
import { Component, OnInit, } from '#angular/core';
import { GridOptions, GridApi, } from "ag-grid-community";
import { ReportersgridComponent } from '../../commonpages/reportersgrid/reportersgrid.component'
#Component({
selector: 'app-reporters',
templateUrl: './reporters.component.html',
styleUrls: ['./reporters.component.scss']
})
export class ReportersComponent implements OnInit {
private reporterGrid: GridOptions;
constructor(public reportersGrid: ReportersgridComponent, ) {
this.reporterGrid = <GridOptions>{};
this.reporterGrid.enableSorting = true;
this.reporterGrid.enableFilter = true;
this.reporterGrid.enableColResize = true;
this.reporterGrid.columnDefs = this.reportersGrid.createColumnDefs();
this.reporterGrid.rowData = this.reportersGrid.createRowData();
}
ngOnInit() {
}
//Search Function
performSearch() {
let searchString = "";
this.populateFiteredReporter(searchString);
// this.reporterGrid.api.setRowData(reporterGrid.rowData)
}
populateFiteredReporter(searchString) {
this.reporterGrid.rowData = [
{ fullName: 'fName,mName,lName2', address: "address2", country: "country2", postcode: "postcode2", phone: "phone", email: "email", qualification: "MBBS", institution: "institution", department: "department" },
];
var str = JSON.stringify(this.reporterGrid.rowData);
console.log('data:' + str);
this.reporterGrid.api.setRowData(this.reporterGrid.rowData);
//this.reportersGrid.populateFiteredReporter(searchString);
}
}
In HTML of the above file, I am using "Base Template" s SELECTOR AS HTML TAG. (
<app-reportersgrid></app-reportersgrid>
) to display the grid portion.
Above gives error -> Cannot read property 'setRowData' of undefined.
Please note that if I replace Base Template's selector with base template's FULL HTML portion for ag-grid (which has (gridReady)="onGridReady($event)"), page works fine.
Can I get help to stick back to my original idea of keeping base template intact? (Note that all base template functions like export to csv, autofit etc works fine - those are coded in the base template along with OnGridReadty().)
Thanks in Advance..
ASJ.
22/10/2019 /* Template of reporters.component.html*/
<div>
<div class="col-md-12">
<div class="card">
<div class="card-header text-uppercase font-weight-bold">
Search
</div>
<div class="card-body">
<div>
<div class="row">
<div class="col-sm-4">
<div class="form-group">
<span>Name <i>(First/Middle/Last)</i></span>
<input type="text" class="form-control" [(ngModel)]="reporterName">
</div>
</div>
</div>
</div>
</div>
<div class="card-footer">
<div class="row">
<div class="col-6 col-sm-4 col-md-2 col-xl mb-3 mb-xl-0">
<button type="button" class="btn btn-normal btn-primary" (click)="performSearch()" style="width: 100px; ">Search</button>
<button type="button" class="btn btn-normal btn-light" style="width: 100px;">Reset</button>
</div>
</div>
</div>
</div>
</div>
<app-reportersgrid></app-reportersgrid>
</div>
Base template - HTML of the AG-GRID
<div class="centered-content">
<div>
<ag-grid-angular #agGrid style="width: 100%; height: 358px;" class="ag-theme-balham"
[gridOptions]="reporterGrid" [enableSorting]="true" enableFilter [sideBar]="sideBar"
enableColResize [pagination]="true" [paginationPageSize]=10
rowDragManaged=true
(gridReady)="onGridReady($event)">
<ag-grid-column headerName="Name" field="fullName"></ag-grid-column>
<ag-grid-column headerName="Address" field="address" [width]="150"></ag-grid-column>
<ag-grid-column headerName="Country" field="country"></ag-grid-column>
<ag-grid-column headerName="Postcode" field="postCode"></ag-grid-column>
<ag-grid-column headerName="Phone" field="phone"></ag-grid-column>
<ag-grid-column headerName="Email" field="email"></ag-grid-column>
<ag-grid-column headerName="Qualification" field="qualification"></ag-grid-column>
<ag-grid-column headerName="Institution" field="institution"></ag-grid-column>
<ag-grid-column headerName="Department" field="department" [cellRenderer]="countryCellRenderer">
</ag-grid-column>
</ag-grid-angular>
</div>
</div>
/ReportersGridcomponent.ts file/
import { Component, OnInit } from '#angular/core';
//import { HttpClient, HttpErrorResponse } from '#angular/common/http';
import {GridOptions, GridApi, Grid} from "ag-grid-community";
#Component({
selector: 'app-reportersgrid',
templateUrl: './reportersgrid.component.html',
styleUrls: ['./reportersgrid.component.scss']
})
export class ReportersgridComponent implements OnInit {
private reporterGrid: GridOptions;
private gridApi:GridApi;
private gridColumnApi;
filterName: string | null;
constructor( ) {
this.reporterGrid = <GridOptions>{};
this.reporterGrid.enableSorting = true;
this.reporterGrid.enableFilter = true;
this.reporterGrid.enableColResize = true;
this.reporterGrid.columnDefs = this.createColumnDefs();
this.reporterGrid.rowData = this.createRowData();
}
ngOnInit() {
}
createColumnDefs() {
this.reporterGrid.columnDefs = [
{
headerName: "Name",
field: "fullName",
width:100,
},
{
headerName: "Address",
field: "address",
},
{
headerName: "Country",
field: "country",
},
{
headerName: "Postcode",
field: "postCode",
},
{
headerName: "Phone",
field: "phone",
},
{
headerName: "Email",
field: "email",
},
{
headerName: "Qualification",
field: "qualification",
},
{
headerName: "Institution",
field: "institution",
},
{
headerName: "Department",
field: "department",
}
];
return this.reporterGrid.columnDefs
}
createRowData(){
this.reporterGrid.rowData = [
// {fullName: 'fName,mName,lName',address:"address1",country: "country",postcode: "postcode",phone: "phone",email:"email",qualification:"MBBS",institution:"institution",department:"department"},
];
return this.reporterGrid.rowData;
}
onGridReady(params) {
this.gridApi = params.api;
this.gridColumnApi = params.columnApi;
this.autoSizeAll()
}
autoSizeAll() {
var allColumnIds = [];
this.gridColumnApi.getAllColumns().forEach(function(column) {
allColumnIds.push(column.colId);
});
this.gridColumnApi.autoSizeColumns(allColumnIds);
}
onCSVExport() {
this.reporterGrid.api.exportDataAsCsv();
}
onSearchTextChange(newData: string) {
this.reporterGrid.api.setQuickFilter(newData);
}
clearFilters() {
if (this.gridApi.isQuickFilterPresent())
{
this.gridApi.setQuickFilter('');
this.filterName="";
}
}
// populateFiteredReporter(searchString){
// this.reporterGrid.rowData = [
// {fullName: 'fName,mName,lName2',address:"address2",country: "country2",postcode: "postcode2",phone: "phone",email:"email",qualification:"MBBS",institution:"institution",department:"department"},
// ];
// var str= JSON.stringify(this.reporterGrid.rowData);
// console.log('data:'+str);
// this.reporterGrid.api.setRowData(this.reporterGrid.rowData);
// //return this.reporterGrid.rowData;
// }
}
The first thing you need to do is set your grid component to accept grid options from its parent:
#Input() public reporterGrid: GridOptions;
Here is an abbreviated version of what your grid component should look like. I suggest using properties or fields, instead of using methods to create your rows and columns. Just a suggestion.
export class ReportersgridComponent implements OnInit {
#Input() public reporterGrid: GridOptions;
private columnDefs = [
// put your column def json here
];
private rowDefs = [
// Put your row def json here
];
constructor() {
}
ngOnInit() {
this.reporterGrid.columnDefs = this.columnDefs;
this.reporterGrid.rowData = this.rowDefs;
}
// rest of your file
}
And your reporters component ts file should look like this:
export class ReportersComponent implements OnInit {
private reporterGridOptions: GridOptions;
constructor() {
this.reporterGridOptions = {
enableSorting: true,
enableFilter: true,
enableColResize: true,
};
}
ngOnInit() {
}
// other code...
}
In your reporter component html, you need to pass in this value through the element like this:
<app-reportersgrid [reporterGrid]="reporterGridOptions"></app-reportersgrid>
Another suggestion, I would take some time to properly name things, adjust casing, and format your code so it is easier to read. I hope this helps get you heading in the right direction. Basically you want to pass your options object to the grid component, so it can have access to it.
Also, you do not want to inject a component through a constructor. It will not be the same instance as the component in the template. Components are initialized and destroyed as they are rendered and removed from the view, and do not exist as singletons like services to.

Applying HTML formatting to React this.setstate

I have an event handler which updates state when a button is clicked which then renders the state to the page. The way this is rendered is not correct and is breaking my UI. My question is, Is it possible to apply formatting directly to the following event handler?
I have attempted to create a nested array so only 1 state is updated but no joy.
see this video for formatting issue I am having: https://www.screencast.com/t/HksUkk7g3G
I have also posted previously about this with the full code here.
React Nested Array
handleAddTelephone = () => {
this.setState({
telephoneType: this.state.telephoneType.concat([{ name: "" }]),
telephone: this.state.telephone.concat([{ name: "" }])
});
};
I need to format each state update. Something like...
handleAddTelephone = () => {
this.setState({
<span>telephoneType: this.state.telephoneType.concat([{ name: "" }])</span>,
<span>telephone: this.state.telephone.concat([{ name: "" }])</span>
});
};
This is my render function. The call to state needs to be around the MDBRow (Bootstrap row class). JSX will not allow this and Im currently using 2 separate calls, one for telephoneType and another for telephone.
<MDBRow className="grey-text no-gutters my-2">
{this.state.telephoneType.map((tt, ttidx) => (
<MDBCol key={ttidx} md="4" className="mr-2">
<select
defaultValue={tt.name}
onChange={this.handleTelephoneTypeChange(ttidx)}
className="browser-default custom-select">
<option value="Mobile">Mobile</option>
<option value="Landline">Landline</option>
<option value="Work">Work</option>
</select>
</MDBCol>
))}
{this.state.telephone.map((tn, tnidx) => (
<MDBCol key={tnidx} md="7" className="d-flex align-items-center">
<input
value={tn.name}
onChange={this.handleTelephoneChange(tnidx)}
placeholder={`Telephone No. #${tnidx + 1}`}
className="form-control"
/>
<MDBIcon icon="minus-circle"
className="mr-0 ml-2 red-text"
onClick={this.handleRemoveTelephone(tnidx)} />
</MDBCol>
))}
</MDBRow>
and the button...
<div className="btn-add" onClick={this.handleAddTelephone}>
<MDBIcon className="mr-1" icon="plus-square" />Add Telephone</div>
<br />
and array...
class InstallerAdd extends React.Component {
constructor() {
super();
this.state = {
role: "Installer",
name: "",
/* telephone: {
type: [{ name: "" }],
number: [{ name: "" }]
}, */
telephoneType: [{ name: "" }],
telephone: [{ name: "" }],
emailType: [{ email: "" }],
email: [{ email: "" }]
};
}

Sending input value with formArray values?

I have a FormArray that can input new fields and can send the value of the whole form on button click, however I am trying to add an input that is tied to the name held within the same object data, but I cannot seem to get it to display let along send with the rest of the updated data...
Here is my blitz
html
<form [formGroup]="myForm">
<div formArrayName="companies">
<!-- I am wanting to update and send the name of the input also... -->
<input formControlName="name"/>
<div *ngFor="let comp of myForm.get('companies').controls; let i=index">
<legend><h3>COMPANY {{i+1}}: </h3></legend>
<div [formGroupName]="i">
<div formArrayName="projects">
<div *ngFor="let project of comp.get('projects').controls; let j=index">
<legend><h4>PROJECT {{j+1}}</h4></legend>
<div [formGroupName]="j">
<label>Project Name:</label>
<input formControlName="projectName" /><span><button (click)="deleteProject(comp.controls.projects, j)">Delete Project</button></span>
</div>
</div>
<button (click)="addNewProject(comp.controls.projects)">Add new Project</button>
</div>
</div>
</div>
</div><br>
<button (click)="submit(myForm.value)">send</button>
</form>
.ts
export class AppComponent {
data = {
companies: [
{
name: "example company",
projects: [
{
projectName: "example project",
}
]
}
]
}
myForm: FormGroup;
constructor(private fb: FormBuilder) {
this.myForm = this.fb.group({
companies: this.fb.array([])
})
this.setCompanies();
}
addNewProject(control) {
control.push(
this.fb.group({
projectName: ['']
}))
}
deleteProject(control, index) {
control.removeAt(index)
}
setCompanies() {
let control = <FormArray>this.myForm.controls.companies;
this.data.companies.forEach(x => {
control.push(this.fb.group({
name: x.name,
projects: this.setProjects(x) }))
})
}
setProjects(x) {
let arr = new FormArray([])
x.projects.forEach(y => {
arr.push(this.fb.group({
projectName: y.projectName
}))
})
return arr;
}
submit(value) {
console.log(value);
}
}
Because you are using a controlArray you will need to move the input within the scope of the [formGroupName]="i" as formControlName="name" is a child of [formGroupName]="i".
<legend><h3>COMPANY {{i+1}}: </h3></legend>
<div [formGroupName]="i">
<input formControlName="name"/>

How to post an object to an array in a json using Angular 6

So I'm testing Angular 6 functionality out for fun to learn it and running a json-server to load a db.json to a localhost server to acquire via service calls which you can see here
{
"customers": {
"testingTitle": "Testing Title",
"trainData":[
{
"id": 1,
"name": "Test Name 1",
"email": "customer001#email.com",
"tel": "0526252525"
},
{
"id": 2,
"name": "Test Name 2",
"email": "customer002#email.com",
"tel": "0527252525"
},
{
"id": 3,
"name": "Customer003",
"email": "customer003#email.com",
"tel": "0528252525"
},
{
"id": 4,
"name": "123",
"email": "123",
"tel": "123"
}
]
}
I have a test.service.ts as followed which picks up the service:
import { Injectable } from '#angular/core';
import {HttpClient, HttpResponse, HttpErrorResponse, HttpHeaders, HttpParams} from '#angular/common/http';
import { Observable } from 'rxjs/Rx';
import { catchError, map } from 'rxjs/operators';
import 'rxjs/add/observable/throw';
const httpOptions = {
headers: new HttpHeaders({ 'Content-Type': 'application/json' })
};
class Test {
testingTitle: string;
trainData:[
{
id : number;
name: string;
email: string;
tel: string;
}
];
}
#Injectable({providedIn: 'root'})
export class TestService {
constructor(private http: HttpClient) {}
public getAllTests(): Observable<Test[]>{
const params = new HttpParams().set('_page', "*").set('_limit', "*");
return this.http.get<Test[]>("http://localhost:3000/customers", {params}).pipe(map(res => res));
}
public postTests(object) {
return this.http.post("http://localhost:3000/customers", object).subscribe(data => {console.log("POST Request is successful ", data);},error => {console.log("Error", error);});
}
}
I have my test.ts which controls my calls etc.
import { Component, OnInit } from '#angular/core';
import { HttpClient } from "#angular/common/http";
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/map';
import {FormBuilder, FormControl, FormGroup} from "#angular/forms";
import {TestService} from "./test.service";
class Customer {
id : number;
name: string;
email: string;
tel: string;
}
#Component({
selector: 'sample-template',
templateUrl: './test.component.html'})
export class TestComponent implements OnInit {
testForm: FormGroup;
testForm2: FormGroup;
public test: any;
name: string = '';
email: string = '';
tel: string = '';
public id: any;
constructor(private httpClient:HttpClient, private fb: FormBuilder, private TestService: TestService) {}
loadTasks(): void{
this.TestService.getAllTests().subscribe(response => {this.test = response;
console.log(this.test)})
}
ngOnInit() {
let trainData = [];
this.loadTasks();
this.testForm = this.fb.group({
testCd: 'Select'
});
this.testForm2 = this.fb.group({
id: this.id,
name: this.name,
email: this.email,
tel: this.tel
})
}
changeDropdown(formControl: FormControl, option: string): void {
formControl.patchValue(option);
console.log(option);
}
submitForm(){
let last:any = this.test[this.test.length-1];
this.id = last.id+1;
console.log(this.id);
this.testForm2.value.id = this.id;
console.log(this.testForm2.value);
this.TestService.postTests(this.testForm2.value);
}
}
And my html page which includes the following:
<label class="modelo-label">{{test?.testingTitle}}</label>
<form [formGroup]="testForm">
<div class="dropdown modelo-dropdown">
<label for="testCd" class="modelo-label">Testing</label>
<button class="btn btn-default dropdown-toggle" data-toggle="dropdown" role="button" id="testCd" aria-haspopup="true" aria-expanded="true">{{testForm.get('testCd').value}}</button>
<div class="dropdown-menu modelo-dropdown-menu" aria-labelledby="testCd">
<a class="dropdown-item" *ngFor="let tests of test?.trainData; let i = index" id="tests.name" (click)="changeDropdown(testForm.get('testCd'), tests.name)">{{tests.name}}</a>
</div>
</div>
<form [formGroup]="testForm2" (ngSubmit)="submitForm()">
<div class="row">
<div class="col-12 col-sm-4 group">
<input type="text" id="name" formControlName="name" class="modelo-text-input"
[ngClass]="{'ng-not-empty' : testForm2.get('name').value.length !== 0}">
<label for="name">Name</label>
</div>
</div>
<div class="row">
<div class="col-12 col-sm-4 group">
<input type="text" id="email" formControlName="email" class="modelo-text-input"
[ngClass]="{'ng-not-empty' : testForm2.get('email').value.length !== 0}">
<label for="email">Email</label>
</div>
</div>
<div class="row">
<div class="col-12 col-sm-4 group">
<input type="text" id="tel" formControlName="tel" class="modelo-text-input"
[ngClass]="{'ng-not-empty' : testForm2.get('tel').value.length !== 0}">
<label for="tel">Telephone #</label>
</div>
</div>
<div class="col-1 group generateButton">
<button class="btn btn-primary" type="submit">Submit Info</button>
</div>
</form>
My Question is, I'm have everything set up for a post and what I'm trying to do is post testForm2.value to the json but under "trainData":[{}] that's within the JSON. I'm able to do so if I just drop all other objects inside the json and have just the array after "customers":... What exactly am I missing? I'm actually confusing myself right now and I may be overthinking this by alot. The post I have currently in this code works if I have just the array after "customers":.... so instead of me passing object which is the testForm2.value what else do I need to do? I hope this makes sense.
You have some strange things in your code. First :
In you API
return this.http.get<Test[]>("http://localhost:3000/customers", {params}).pipe(map(res => res));
I think what you want to do here is : (the pipe is useless you dont use it and it's not an array)
return this.http.get<Test>("http://localhost:3000/customers",{params});
In your component you want to push the update trainData list
submitForm(){
const lastTrainData = this.test.trainData[this.test.trainData.length-1];
const newTrainData = this.testForm2.value;
newTrainData.id = lastTrainData.id + 1;
this.test.trainData.push(newTrainData);
this.TestService.postTests(this.test);
}

Angular 6 Dynamic checkbox form "Error: Cannot find control with name: 'P1'"

I"m trying to find a way to show dynamic form that contains a column of checkboxes. after following a nice youtube guide my code behaves differently, not working.
problem: even that i can see that the form controls name are p1,p2,p3.. etc
and the form looking for this controls. they wont load, wont connect and return this msg: Error: Cannot find control with name: 'P1'
so here i"m looking for help again. or a good link with a nice guide will be appreciated.
JSON file
platformsArray = [
{
platform_id: 'P1',
platform_name: "Facebook",
platform_weight: 0.5,
selected: true
},
{
platform_id: 'P2',
platform_name: "Instragram",
platform_weight: 0.7,
selected: true
},
{
platform_id: 'P3',
platform_name: "Google",
platform_weight: 0.2,
selected: true
},
{
platform_id: 'p4',
platform_name: "AdWords",
platform_weight: 0.6,
selected: true
},
{
platform_id: 'p5',
platform_name: "Google My Business",
platform_weight: 0.15,
selected: true
}
];
comp.ts
//platforms form
platformForm: FormGroup;
constructor(private router: Router, private fb: FormBuilder ) {
this.platformForm = fb.group({
P1: [],
P2: [],
P3: [],
p4: [],
p5: [],
platforms: this.buildPlatforms()
});
//here we construct the controls
buildPlatforms() {
const arr = this.platformsArray.map(platform => {
return this.fb.control(platform.platform_id);
});
console.log(arr)
return this.fb.array(arr);
}
call and submit
submit(platformForm) {
console.log(platformForm)
}
html
<!-- platform form -->
<form [formGroup]="platformForm" (ngSubmit)="submit(platformForm.value)">
<!-- Default unchecked -->
<div *ngFor="let platform of platformsArray; let i=index" class="custom-control custom-checkbox" (ngSubmit)="submit()">
<input type="checkbox" class="custom-control-input" [formControlName]="platform.platform_id" [id]="platform.platform_id" checked>
<label class="custom-control-label" [for]="platform.platform_id">{{platform.platform_name}}</label>
</div>
<div class="text-center">
<button type="submit" class="btn btn-success btn-md">Sign in</button>
</div>
</form>
<!-- platform form -->
Please notice that im new to this. so i still trying to understand what happaning here. Thanks for the help :-)
Try something like this:
DEMO
<form [formGroup]="platformForm" (ngSubmit)="submit()">
<div formArrayName="platforms">
<div *ngFor="let item of platformForm.get('platforms').controls; let i = index;" [formGroupName]="i">
<div style="margin: 10px;">{{item.value | json }}</div>
<div>
<input type="checkbox" formControlName="platform_id" checked>
<label>{{platformForm.controls.platforms.controls[i].controls.platform_name.value}}</label>
</div>
</div>
<div>
<button type="submit">Submit</button>
</div>
</div>
</form>
TS:
platforms: FormArray;
platformForm: FormGroup;
constructor(private fb: FormBuilder) {
}
ngOnInit() {
this.createForm();
this.platforms = this.getData();
while (this.getData().length) {
this.platforms.removeAt(0)
}
for (let d of this.platformsArray) {
this.addMore(d);
}
}
getData() {
return this.platformForm.get('platforms') as FormArray;
}
addMore(d) {
this.getData().push(this.buildPlatforms(d));
}
createForm() {
this.platformForm = this.fb.group({
platforms: this.fb.array([this.buildPlatforms({
platform_id: null,
platform_name: null,
platform_weight: null,
selected: null
})])
});
}
buildPlatforms(data) {
if (!data) {
data = {
platform_id: null,
platform_name: null,
platform_weight: null,
selected: null
}
}
return this.fb.group({
platform_id: data.platform_id,
platform_name: data.platform_name,
platform_weight: data.platform_weight,
selected: data.selected
});
}
submit() {
console.log(this.platformForm.value)
}