Neal Deters Neal Deters - 3 months ago 14
AngularJS Question

Convert nested array of objects into nested property template object

I have an array of objects created that I would like to convert into a nested property template object. The nested object will be created based on items that are checked.

The first level of objects have their 'checked' key set to null as they will always be added as the beginning of the property template object.

If the first level objects have no properties, or the none of the properties are checked, then it should look like this:

{staff: true}


However, if the objects have properties and some of the properties are checked, it will look like this:

{staffedLocation: ['schedulingGroup',
{property: 'staff', subProperties: ['description']}
]
}


This is a very simple example and in some cases the array of nested objects can go further down, so I know I need to create a recursive function. However, I'm getting tripped up as to how I can go about creating it recursively when the first level of the object is entirely different from the rest of it.

An example of the array of objects on hand looks like this:

[
{checked: null, name: "staffedLocation", properties: [
{checked: null, name: "oid", properties: null, toggle: null, type: "integer"},
{checked: null, name: "_class", properties: null, toggle: null, type: "string"},
{checked: true, name: "schedulingGroups", properties: null, toggle: null, type: "list"},
{checked: null, name: "staff", properties: [
{checked: null, name: "oid", properties: null, toggle: null, type: "integer"},
{checked: null, name: "_class", properties: null, toggle: null, type: "string"},
{checked: true, name: "description", properties: null, toggle: null, type: "string"},
{checked: null, name: "limits", properties: null, toggle: null, type: "list"},
{checked: null, name: "weeklyMaxHours", properties: null, toggle: null, type: "integer"}

], toggle: true, type: "list"},
], toggle: true, type: "staffedLocation"},
{checked: null,
name: "staff", properties: [
{checked: null, name: "oid", properties: null, toggle: null, type: "integer"},
{checked: null, name: "_class", properties: null, toggle: null, type: "string"},
{checked: null, name: "description", properties: null, toggle: null, type: "string"},
{checked: null, name: "limits", properties: null, toggle: null, type: "list"},
{checked: null, name: "weeklyMaxHours", properties: null, toggle: null, type: "integer"}
], toggle: true, type: "staff"},
{checked: null, name: "assignedShifts", properties: null, toggle: null, type: "shiftForEmail"},
{checked: null, name: "editedShifts", properties: null, toggle: null, type: "shiftForEmail"},
{checked: null, name: "deletedShifts", properties: null, toggle: null, type: "shiftForEmail"},
{checked: null, name: "unassignedShifts", properties: null, toggle: null, type: "shiftForEmail"},
{checked: null, name: "rangeStart", properties: null, toggle: null, type: "timestamp"},
{checked: null, name: "rangeEnd", properties: null, toggle: null, type: "timestamp"}
]


And I would like it to then be converted into a nested object like so:

{
staffedLocation: ['schedulingGroup',{property: 'staff',subProperties: ['description']}],
staff: true,
assignedShifts: true,
editedShifts: true,
deletedShifts: true,
unassignedShifts: true,
rangeStart: true,
rangeEnd: true
}

Answer

What you actually need is to apply your recursive function only to the properties of the topmost object, and not to the topmost object itself:

// No ES6 sugar
function convert(content) {

function convertValues(props) {
    if (!(props && props.length && props.length > 0)) {
        return true;
    }
    var convertedProps = [];

    props.forEach(function(prop) {
       // Recursive
       var values = convertValues(prop.properties);
       if (prop.checked || values.length) {

           convertedProps.push(prop.name, values);
       }
    });

    return convertedProps;
}

var convertedContent = {};

content.forEach(function(obj) {
    convertedContent[obj.name] = convertValues(obj.properties);
});

return convertedContent;

}

I don't think that's the exact code you want, but hope it gives you direction.

Comments