Flatten a deeply nested object using JavaScript

Viewed 125

I have an object with a triple nested objects. I want to flatten the object to clearly review the values and place in an HTML.

{
    "templateName": "Test template",
    "assignmentGroup": "Test template",
    "fields": [{
        "type": "Multi Select dropdown",
        "entry": [{
            "checked": false,
            "value": "govtBusinses",
            "displayValue": "Government Business Division"
        }, {
            "checked": true,
            "value": "privateSector",
            "displayValue": "Private Sector"
        }, {
            "checked": true,
            "value": "publicSector",   
            "displayValue": "Public Sector"
        }]
    }, {
        "type": "Text Field",
        "entry": null
    }]
}

I tried flatting it, but I want it to be in desired format.

flattenObject = function(ob) {
        let toReturn = {};
        for (let i in ob) {
            if (!ob.hasOwnProperty(i)) {
                continue;
            }
            if ((typeof ob[i]) === "object") {
                let flatObject = this.flattenObject(ob[i]);
                for (let x in flatObject) {
                    if (!flatObject.hasOwnProperty(x)) {
                        continue;
                    }
                    toReturn[i + "." + x] = flatObject[x];
                }
            } else {
                toReturn[i] = ob[i];
            }
        }
        console.log(toReturn);
        return toReturn;
    };

Expected:

TemplateName  : "Test template"
Assignment Group : "sample"
Field 0 :
Type : Multiselect dropdown
Entry 0 :
checked : false
value : 
buisness: 
Entry 1:
checked : false
value : 
buisness: 
Field 1:
Type: 
.......

How can i achieve this?

1 Answers

You can't have different values with same Key in object. I guess better way to achieve this would be to return array of objects instead.

try this:

let obj = {
  "templateName": "Test template",
  "assignmentGroup": "Test template",
  "fields": [{
    "type": "Multi Select dropdown",
    "entry": [{
      "checked": false,
      "value": "govtBusinses",
      "displayValue": "Government Business Division"
    }, {
      "checked": true,
      "value": "privateSector",
      "displayValue": "Private Sector"
    }, {
      "checked": true,
      "value": "publicSector",
      "displayValue": "Public Sector"
    }]
  }, {
    "type": "Text Field",
    "entry": null
  }]
}

let fieldsCount = []

flattenObject = function(ob, toReturnArr) {
  for (let i in ob) {
    if (!ob.hasOwnProperty(i)) {
      continue;
    }
    if ((typeof ob[i]) === "object") {
      if (isNaN(i)) {
        fieldsCount[i] = fieldsCount[i] === undefined ? 0 : fieldsCount[i] + 1
        ob[i] && ob[i].length ? console.log(`${i}: ${fieldsCount[i]}`) : null;
      }
      toReturnArr = this.flattenObject(ob[i], toReturnArr);
    } else {
      console.log(`${i}: ${ob[i]}`);
      toReturnArr.push({
        [i]: ob[i]
      })
    }
  }
  return toReturnArr;
};

flattenObject(obj, [])

Result:

templateName: Test template
assignmentGroup: Test template
fields: 0
type: Multi Select dropdown
entry: 0
checked: false
value: govtBusinses
displayValue: Government Business Division
checked: true
value: privateSector
displayValue: Private Sector
checked: true
value: publicSector
displayValue: Public Sector
type: Text Field

PS: {[key]: object[key]} using variable for key value like [key] is the ES6 feature.

Related