Reputation: 51
I came across the following Stackblitz demo :
https://stackblitz.com/edit/angular-dffny7?file=app
with reference to the below post: https://stackoverflow.com/a/48527939/7429196
Now suppose I have the following JSON
{
"companies": [
{
"company": "ABC",
"projects": [
{
"projectName": "DEF"
},
{
"projectName": "GHI"
}
]
},
{
"company": "JKL",
"projects": [
{
"projectName": "MNO"
}
]
}
]
}
coming from following service:
getCompanies() : Observable<Organization>{
return this.http.get(url).map((response: Response)=> response.json())}
and the Organization class is as following :
export class Organization{
public company: String;
public projects : Project[];
}
export class Project{
public projectName : String;
}
I have the above JSON data in the object of Organization class in my component file and I want to render this data in the form fields in the html file. I tried binding the data using ngModel but read it somewhere that ngModel cannot be used in a model-driven form. How can I achieve it?
Upvotes: 0
Views: 4146
Reputation: 57909
@Random Guy, the key to pass data from json to a FormBuilder is using the "map" method of arrays. But At first, please use HttpClient NOT the old and deprecated http (so, you needn't use this ugly map((response: Response)=> response.json())}
Well, you import in constructor the formBuilder
constructor (private fb:FormBuilder){}
And make a function that receive as argument your json or null and return a fromGroup
createForm(data: any): FormGroup {
return this.fb.group({
//id data.companies, we create a formArray
companies: data ? this.fb.array(this.createGroupProjects(data.companies)) : []
})
}
//return an array of FormGroups
createGroupProjects(companies: any[]): FormGroup[] {
//with each element in companies
return companies.map(c => {
//create a formGroup
return this.fb.group({
company: c.company,
//projects will be a form array too
projects: this.fb.array(this.createProjects(c.projects))
})
})
}
//return an array of FormGroups
createProjects(projects: any[]): FormGroup[] {
//with each project
return projects.map(p => {
//return a FormGroup
return this.fb.group({
projectName: p.projectName
})
})
}
Of course you can use only a function
createForm(data: any): FormGroup {
return this.fb.group({
//in "companies" if data.companies, we return a FormArray
//with each element of data.companies we return a formGroup
companies: data ? this.fb.array(data.companies.map(c => {
return this.fb.group({
company: c.company,
//the propertie projects will be another FormArray
//with each element in projects
projects: this.fb.array(c.projects.map(p => {
//return a formGroup
return this.fb.group({
projectName: p.projectName
})
}))
})
}))
//If data=null, you return an array
: []
})
}
See that yours FormArray are created using this.bt.array(...a formGroup array...), and this formGroupArray is created using "map".
Upvotes: 1