1

FormArrayThe formObj has array of componentDetails Object which in turn has a nested array of component array.

   export class FormViewComponent implements OnInit {

    public callbackForm: FormGroup;

    formObj = {
        "componentDetails": [{
            "component": [{
                "value": "Choice 1"
            }, {
                "value": "Choice 2"
            }],
            "cpv": "",
            "label": "Description of Problem",
            "type": "radio",
            "mandatory": true
        }]
    };

    loadObservableForm() {
        this.formService.getData(this.id)
            .subscribe(
                (formObj) => {
                    this.formObj = formObj;
                    this.callbackForm = this._formBuild.group({
                        componentDetails: this._formBuild.array([])
                    });
                    this.addComponentDetails();
                },
                (err) => console.error(err),
                () => console.log('observable complete')
            );

    }

    addComponentDetails() {
        const control = <FormArray> this.callbackForm.controls.componentDetails;
        this.formObj.componentDetails.forEach(x => {
            control.push(this.addControl(x));
        });
    }

    addControl(x) {
        const group = this._formBuild.group({
            label: x.label,
            cpv: x.cpv,
            type: x.type,
            mandatory: x.mandatory,
            component: this._formBuild.array([this.addOptions(x)])
        });
        return group;
    }

    addOptions(z) {
        const control = < FormArray > z.component;
        z.component.forEach(y => {
            control.push(this.addOptionRow(y.value));
        });
    }

    addOptionRow(value) {
        return this._formBuild.group({
            value: value
        });
    }
}

Template HTML:

<form [formGroup]="callbackForm">
    <div>
        <div formArrayName="componentDetails">
            <div *ngFor="let question of callbackForm.controls.componentDetails.controls; let i = index;" [formGroupName]="i">
            <div class="row">
                <div class="col-md-12 panel-group panel-group--compressed">
                    <div class="panel panel--default">
                        <fieldset>
                            <div class="row" *ngIf="question.controls.type.value === 'radio'">
                                <div class="col-md-12">
                                    <p>{{ question.controls.label.value }}</p>
                                    <div formArrayName="component">
                                        <div *ngFor="let answer of question.controls.component.controls; let j = index" [formGroupName]="j">
                                        <label class="radio radio--alt radio--stacked">
                                        <input type="radio" name="radio-stacked">
                                        <span class="radio__input"></span>
                                        <span class="radio__label">{{ answer.value }}</span>
                                        </label>
                                    </div>
                                </div>
                            </div>
                    </div>
                    </fieldset>
                </div>
            </div>
        </div>
    </div>
    </div>
    </div>
</form>

Problem:

In the component template HTML, I cannot get the value for {{ answer.value }}. I tried with answer.controls.value.value and answer.controls.value. And nothing is working. question.controls.component.controls returns [Object Object]

7
  • Here is a good article about "Nested model-driven forms": scotch.io/tutorials/… There are some plunkr so you'll be able to play with it and test a solution for your need. Commented Oct 18, 2017 at 6:37
  • Have you tried using return group instead of question.push(group); in addOption method? Commented Oct 27, 2017 at 4:09
  • Sorry, return group did not work :( Commented Nov 15, 2017 at 6:52
  • Is this code at all working? When I try it, the formarray is null? Commented Nov 24, 2017 at 4:46
  • I get the formObj as a JSON by calling an API. console.log(controls) inside addComponentDetails returns FormArray. I have added the screenshot of FormArray in the question Commented Nov 24, 2017 at 6:37

1 Answer 1

3

You have trouble when calling addOptions inside the form array:

component: this._formBuild.array([this.addOptions(x)])

Place that below instead, so this will work. I omitted addOptions and addOptionRow from your code and instead applied the logic in addControl:

addControl(x) {
  const group = this._formBuild.group({
    label: x.label,
    cpv: x.cpv,
    type: x.type,
    mandatory: x.mandatory,
    component: this._formBuild.array([])
  });
  const ctrl = group.controls.component as FormArray;
  x.component.forEach(y => {
    ctrl.push(this._formBuild.group({
      value: y.value
    }))
  })
  return group;
}

and your template is otherwise correct, but to show the label do:

{{ answer.value.value }}

instead of

{{ answer.value }}

StackBlitz

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

3 Comments

I can't get the selectedValue (Choice 1 or Choice 2) of the radio in the <pre>{{callbackForm.value | json }}</pre> for sending the selectedValue on Form Submission
I forked your stackblitz to add selectedValue with the formObj to capture the radio selection. Not sure if it's right approach? stackoverflow.com/questions/47518664/…
Hi @AJT_82, could you please let me know how to get the selected Value on Form Submission? Thank you!

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.