0

I will be getting list of items and their hobbylist from backend, User should able to edit/add.

let item of ['item1', 'item2', 'item3']

(ngSubmit) value;

I want to following output:

item1: {
hobbyList: Array[0]
name: null
}, 
item2: {
hobbyList: Array[0]
name: null
}, 
item3: {
hobbyList: Array[0]
name: null
}

I have tried doing this but getting below error

ERROR
Error: Cannot find control with name: 'item1.hobbyList'
Unable to display error. Open your browser's console to view.

Is there any other way to achieve this.

Link : What i have tried so far Stackblitz: https://stackblitz.com/edit/angular-qsq3yb?file=src%2Fapp%2Fapp.component.ts

2 Answers 2

1

stackblitz

  public myForm: FormGroup;

  ngOnInit() {
    this.myForm = new FormGroup({});
    for(let item of ['item1', 'item2', 'item3']) {
      this.myForm.addControl(item,
        new FormGroup({
          name: new FormControl(),
          hobbyList: new FormArray([])
        })
      )
    } 
  } 

  onAddHobby(group:FormGroup) {
    (group.get('hobbyList') as FormArray).push(new FormControl())
  }

  hobbiesArray(group:FormGroup):FormArray
  {
    return group.get('hobbyList') as FormArray
  }

The .html

<form [formGroup]="myForm">
    <ng-container *ngFor="let group of myForm.controls |keyvalue">
        <div style="margin:20px;" [formGroup]="group.value">
            <label for="">{{group.key}}</label>
            <input type="text" formControlName="name">
            <button type="button" (click)="onAddHobby(group.value)">Add Hobbies</button>
            <div formArrayName="hobbyList">
                <div *ngFor="let item of hobbiesArray(group.value).controls; let i = index">
                    <label for="">Hobbies</label>
                    <input [formControlName]="i">
      </div>
                </div>
        </div>
    </ng-container>
</form>
<pre>
{{myForm?.value|json}}
</pre>

But let me explain a bit the code. You has a FormGroup with three FormGroup, each of them has a FormControl and a FormArray. I like iterate always over the form of over elements of the form, it's the reason to iterate over some "bizarro" like let group of myForm.controls |keyvalue under this div, group.value will be each FormGroup, and group.key will be the name of the propertie.

As is a FormGroup, we create a div with this [formGroup]

<div style="margin:20px;" [formGroup]="group.value">
 ...
</div>

Under this div, we ask about the formControl "name" using

<input type="text" formControlName="name">

And about the formArray like

<div formArrayName="hobbyList">

We has a function to get the formArray, hobbiesArray(group.value) that pass the FormGroup, identically in onAddHobby we pass the FormGrorup

Sign up to request clarification or add additional context in comments.

3 Comments

Before you ask it, I just updated the stackblitz to allow remove "hobies"
Thank you @Eliseo :), It means a lot to me. i was not aware of that we will able to send group.value to ts and achieve this.
Hey @Eliseo, Can you check this one also which is similar to this: stackoverflow.com/questions/58390040/…
1

if you want to create the following array:

item1: {
    hobbyList: Array[0]
    name: null
}, 
item2: {
    hobbyList: Array[0]
    name: null
}, 
item3: {
    hobbyList: Array[0]
    name: null
}

then you need just to use map function:

let fooArray = ['item1', 'item2', 'item3'];
let desiredArray = fooArray.map(a => {
    let obj = {};
    obj[a] = {
        hobbyList:[],
        name : ''
    };
    return obj;
});
console.log(desiredArray);

1 Comment

Can you please check this link: stackblitz.com/edit/…, Your answer isnt related to post.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.