1

I have a complex nested array and I have the data in a object with nested array. I want to display all the data in edit view. I tried it in stackblitz and have issues in loading data . The link is enter link description here

I want to load second level array (groups) in the form text box. Thanks in advance.

3
  • Can you please tell what exactly is your problem? What you are not getting? Commented Sep 3, 2018 at 17:53
  • I want to load second level array (groups) in the form text box. Commented Sep 3, 2018 at 17:58
  • Your problem is that your t variable is not the json, you are reading the forms controls and after, you are doing: "t['groups']" t is a formControl, it's not your json, you are doing a strange thing there xD Commented Sep 3, 2018 at 18:17

1 Answer 1

8

You will have to create getters and in some cases, methods that return FormArrays.

Here's how:

import { Component, OnInit } from '@angular/core';
import { FormGroup, FormBuilder, FormArray } from '@angular/forms';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {

  data: any[];
  form: FormGroup;

  get tasks() {
    return ( < FormArray > this.form.get('tasks')).controls;
  }

  getGroupsFor(index) {
    return ( < FormArray > ( < FormArray > this.form.get('tasks')).controls[index].get('groups')).controls;
  }

  getDictionaryFor(index) {
    return ( < FormArray > ( < FormArray > this.form.get('tasks')).controls[index].get('dictionary')).controls;
  }

  getAttributesFor(taskIndex, groupIndex) {
    return ( < FormArray > ( < FormArray > ( < FormArray > this.form.get('tasks')).controls[taskIndex].get('groups')).controls[groupIndex].get('attributes')).controls;
  }

  constructor(private fb: FormBuilder) {}

  ngOnInit() {
    this.loadData();
    this.form = this.fb.group({
      lessoncode: 'TMM',
      countrycode: 'CA',
      languagecode: 'en',
      tasks: this.fb.array(this.getTasks())
    });
    console.log('Form Value', this.form.value);
  }

  getTasks() {
    return this.data.map(task => this.fb.group({
      taskid: task.taskid,
      taskname: task.taskname,
      groups: this.fb.array(this.getGroups(task.groups)),
      dictionary: this.fb.array(this.getDictionaries(task.dictionary))
    }));
  }

  getDictionaries(dictionaries: any[]) {
    return dictionaries.map(dictionary => this.fb.group({
      content_id: dictionary.content_id,
      term: dictionary.term,
      translation_id: dictionary.translation_id,
      value: dictionary.value,
      task_id: dictionary.task_id,
      task_dictionary_id: dictionary.task_dictionary_id,
      isnew: dictionary.isnew,
      altered: dictionary.altered
    }));
  }

  getGroups(groups: any[]) {
    return groups.map(group => this.fb.group({
      id: group.id,
      name: group.name,
      attributes: this.fb.array(this.getAttributes(group.attributes))
    }));
  }

  getAttributes(attributes: any[]) {
    return attributes.map(attribute => this.fb.group({
      name: attribute.name,
      contentid: attribute.contentid,
      value: attribute.value,
      translationvalue: attribute.translationvalue,
      placeholder: attribute.placeholder,
      label: attribute.label,
      defaultvalue: attribute.defaultvalue,
      type: attribute.type,
      element: attribute.element,
      altered: attribute.altered,
      translation_id: attribute.translation_id,
      isnew: attribute.isnew
    }));
  }

  loadData() {
    this.data = [{
        "taskid": 31,
        "taskname": "intro",
        "groups": [{
          "id": 223,
          "name": "Fullscreen Image and Sub-Heading",
          "attributes": [{
              "name": "Main Heading",
              "contentid": 767,
              "value": "Multitasking",
              "translationvalue": "Realización de varias tareas al mismo tiempo",
              "placeholder": "Main Heading",
              "label": "Main Heading",
              "defaultvalue": "",
              "type": "text",
              "element": "input",
              "altered": false,
              "translation_id": 3063,
              "isnew": false
            },
            {
              "name": "Sub-Heading",
              "contentid": 155,
              "value": "Driver Attitude",
              "translationvalue": "Actitud del conductor",
              "placeholder": "Type Heading",
              "label": "Sub-Heading",
              "defaultvalue": "",
              "type": "text",
              "element": "input",
              "altered": false,
              "translation_id": 3064,
              "isnew": false
            },
            {
              "name": "Full-Screen Image",
              "contentid": 211,
              "value": "/media/lessons/dst/intro/image01-right.jpg",
              "translationvalue": null,
              "placeholder": "Image Url",
              "label": "Full-Screen Image",
              "defaultvalue": "",
              "type": "image",
              "element": "input",
              "altered": false,
              "translation_id": null,
              "isnew": true
            },
            {
              "name": "Full-Screen Image",
              "contentid": 212,
              "value": "/media/lessons/dst/intro/image01-left.jpg",
              "translationvalue": null,
              "placeholder": "Image Url",
              "label": "Full-Screen Image",
              "defaultvalue": "",
              "type": "image",
              "element": "input",
              "altered": false,
              "translation_id": null,
              "isnew": true
            },
            {
              "name": "Full-Screen Image",
              "contentid": 213,
              "value": "/media/lessons/dst/intro/image01-right.jpg",
              "translationvalue": null,
              "placeholder": "Image Url",
              "label": "Full-Screen Image",
              "defaultvalue": "",
              "type": "image",
              "element": "input",
              "altered": false,
              "translation_id": null,
              "isnew": true
            },
            {
              "name": "Full-Screen Image Alt",
              "contentid": 880,
              "value": "Multitasking - Driver Attitude",
              "translationvalue": "Multitasking - Driver Attitude",
              "placeholder": "Full-Screen Image Alt",
              "label": "Full-Screen Image Alt",
              "defaultvalue": "",
              "type": "alt",
              "element": "input",
              "altered": false,
              "translation_id": 3062,
              "isnew": false
            },
            {
              "name": "Icon SVG Data",
              "contentid": 3063,
              "value": "",
              "translationvalue": null,
              "placeholder": "SVG Data",
              "label": "Icon SVG Data",
              "defaultvalue": "",
              "type": "html",
              "element": "textarea",
              "altered": false,
              "translation_id": null,
              "isnew": true
            }
          ]
        }],
        "dictionary": [{
          "content_id": 5,
          "term": "Continue",
          "translation_id": 3065,
          "value": "Continuar",
          "task_id": 31,
          "task_dictionary_id": 11,
          "isnew": 0,
          "altered": 0
        }]
      },
      {
        "taskid": 32,
        "taskname": "question-1",
        "groups": [{
          "id": 228,
          "name": "Question",
          "attributes": [{
              "name": "Question Text",
              "contentid": 956,
              "value": "Welcome to the Multitasking exercise. Before we begin, please select the statement that best describes your current view on the subject.",
              "translationvalue": "Bienvenido al ejercicio sobre realización de varias tareas al mismo tiempo. Antes de comenzar, seleccione la afirmación que mejor describa su opinión actual sobre el tema.",
              "placeholder": "Question Text",
              "label": "Question Text",
              "defaultvalue": "",
              "type": "textarea",
              "element": "textarea",
              "altered": false,
              "translation_id": 3462,
              "isnew": false
            },
            {
              "name": "Randomize Answers",
              "contentid": 1100,
              "value": "1",
              "translationvalue": null,
              "placeholder": "Randomize Answers",
              "label": "Randomize Answers",
              "defaultvalue": "2",
              "type": "truefalse",
              "element": "select",
              "altered": false,
              "translation_id": null,
              "isnew": true
            }
          ]
        }],
        "dictionary": []
      }
    ];
  }
}

And this is going to be your Template:

<form [formGroup]="form">
  <input type="text" formControlName="lessoncode" />
  <input type="text" formControlName="countrycode" />
  <input type="text" formControlName="languagecode" />

  <div formArrayName="tasks">
    <div *ngFor="let task of tasks;let taskIndex=index;">
      <h1>Tasks</h1>
      <div [formGroupName]="taskIndex">
        <input formControlName="taskid" />
        <input formControlName="taskname" />
        <div formArrayName="groups">
          <div *ngFor="let group of getGroupsFor(taskIndex);let groupIndex=index;">
            <h2>Group</h2>
            <div [formGroupName]="groupIndex">
              <input formControlName="id" />
              <input formControlName="name" />
              <div formArrayName="attributes">
                <div *ngFor="let attribute of getAttributesFor(taskIndex, groupIndex);let attributeIndex=index;">
                  <h3>Attribute</h3>
                  <div [formGroupName]="attributeIndex">
                    <input formControlName="name" />
                    <input formControlName="contentid" />
                    <input formControlName="value" />
                    <input formControlName="translationvalue" />
                    <input formControlName="placeholder" />
                    <input formControlName="label" />
                    <input formControlName="defaultvalue" />
                    <input formControlName="type" />
                    <input formControlName="element" />
                    <input formControlName="altered" />
                    <input formControlName="translation_id" />
                    <input formControlName="isnew" />
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>

        <div formArrayName="dictionary">
          <div *ngFor="let dict of getDictionaryFor(taskIndex); let dictIndex=index;">
            <h2>Dictionary</h2>
            <div [formGroupName]="dictIndex">
              <input formControlName="content_id" />
              <input formControlName="term" />
              <input formControlName="translation_id" />
              <input formControlName="value" />
              <input formControlName="task_id" />
              <input formControlName="task_dictionary_id" />
              <input formControlName="isnew" />
              <input formControlName="altered" />
            </div>
          </div>
        </div>

      </div>
    </div>
  </div>
</form>

I've literally spent about an hour creating this for you. But this was fun. Here's a StackBlitz for your referece.

Hope it helps.

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

3 Comments

Thanks Siddharth for your help and happy then you had fun :) I learnt the advanced Technic from your code... thanks again.
I optimized the code (single component to multiple child components) .Here is the link . stackblitz.com/edit/angular-nested-forms-reactive?file=src/app/…
You might want to fork it first and then post it. This was just to give you some idea of how to do it in a single component.

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.