5
votes

I have a nested JSON response coming back from an API and is structured differently then how I need to display it on the template, for example:

@Component({
  selector: 'reactive-form-example',
  styles: ['./reactive-form-example.component.css'],
  template: `
    <form [formGroup]="form" (ngSubmit)="onSubmit()">
        <div formGroupName="first">
            <input type="text" placeholder="some id" formControlName="someId">
            <div formGroupName="second">
                <input type="text" placeholder="some text" formControlName="someText">
            </div>
        </div>
    </form>
  `
})
export class ReactiveFormExampleComponent {
    form = new FormGroup({
        first: new FormGroup({
            someId: new FormControl('587824')
        }),
        second: new FormGroup({
            someText: new FormControl('the sky is blue')
        })
    });
    onSubmit(value) {
        console.log('Submit', this.form.value);
    }
}

Question: Is it possible to have a formGroupName nested within another formGroupName, or is there a better way to achieve this same result using reactive forms?

1
can you try [formGroup]="form.get('first')" instead of formGroupName="first"shehata
@emostafa that works! is this good practice?Jordan Davis
to be honest, I am not sure, but i think it is, in the angular docs under nested form groups, you will find a section about it. angular.io/guide/reactive-forms#more-formcontrolsshehata

1 Answers

8
votes

Yes. formGroupName can be nested within another formGroupName.

formGroupName and formControlName attributes work by finding a control with that particular name within the parent FormGroup.

Note that your problem is caused because you're trying to find a FormGroup named second within the first FormGroup:

<form [formGroup]="form">
    <div formGroupName="first">
        <div formGroupName="second">
        </div>
    </div>
</form>

To make that work, you'd have to adapt your model as follows, where second becomes a child of first:

form = new FormGroup({
    first: new FormGroup({
        someId: new FormControl('587824'),
        second: new FormGroup({
            someText: new FormControl('the sky is blue')
        })
    }),        
});

The reason why the suggestion of emostafa works, is because you ask the form instance to get a direct child named second within the model. Which does exist in this case.