Neal Deters Neal Deters - 3 months ago 11
AngularJS Question

Recreate an array of nested objects recursively

I have an array of nested objects created by a user. I need to recursively check the array for if checked is set to true and recreate the nested array of objects as shown below.

With my original attempt I was able to recursively get through the nested array. However, every time it recursed I would overwrite my previous information.

$scope.newPropertyTemplate = [];

function checkProps (item, props){
debugger
var obj = {};
var arr = [];

for(var i in props){

if(props[i].checked === true){
obj.property = item;
arr.push(props[i].name);
obj.subProperties = arr;
}

if(props[i].properties){
checkProps(props[i].name, props[i].properties);
}
}

return obj;
}

for(var i = 0; i < $scope.propertyTemplate.length; i++){

if($scope.propertyTemplate[i].properties !== null){

$scope.newPropertyTemplate.push(checkProps($scope.propertyTemplate[i].name, $scope.propertyTemplate[i].properties));
// $scope.newPropertyTemplate.push( newItem.property = $scope.propertyTemplate[i].name );
}
else {
$scope.newPropertyTemplate.push($scope.propertyTemplate[i].name);
}
}


Here's an example of the nested array:

[
{name: "allocation",
properties:[
{
name: "oid",
checked: true,
properties: null,
type: "integer"
},
{
name: "person",
checked: false,
properties: [
{
name: "Expires",
checked: true,
properties: null,
type: "timestamp"
},
{
name: "State/Province",
checked: true,
properties: null,
type: "string"
}
]
],
type: "allocation"
]


Here's an example of the converted array of objects:

[
{property: "allocation",
subProperties: [
"oid",
{property: "person",
subProperties: [
"Expires",
"State/Province"
]
}
]
}
]

Answer

This should work. The returned obj from your recursive checkProps function was not being stored.

var data = [{
  name: "allocation",
  properties: [{
      name: "oid",
      checked: true,
      properties: null,
      type: "integer"
    }, {
      name: "person",
      checked: false,
      properties: [{
        name: "Expires",
        checked: true,
        properties: null,
        type: "timestamp"
      }, {
        name: "State/Province",
        checked: true,
        properties: null,
        type: "string"
      }]
    },

  ],
  type: "allocation"
}];

function process(paths) {
  var arr = [];
  data.forEach(function(template) {
    var resultObj = {};
    recurse(template, resultObj);
    arr.push(resultObj);
  });
  console.log(arr);
}

function recurse(template, obj) {
  obj.property = template.name;
  if (template.properties == null)
    return;
  obj.subProperties = [];
  template.properties.forEach(function(prop) {
    var res = {};
    if (prop.properties != null)
      recurse(prop, res);
    else if (prop.checked)
      res = prop.name;
    if (res)
      obj.subProperties.push(res);
  });;
}

process(data);