Skip to content
Advertisement

Recreate an object from an array of objects in Javascript

I could use some help with the following:

I’m trying to create a filterable wordpress nav menu using React Tree Menu.

The Tree Menu component requires the following data structure:

{
    "Home" : {
      checkbox: false,
      ID: 1,
      children: {
        "Getting Started" : {
          checkbox: false,
          ID: 47,
          slug: 'getting-started',
        },
        "Interaction Design Principles": {
          checkbox: false,
          children: {
            "Design Principle the First" : {
              selected: false,
              checkbox: false,
              ID: 67
            }
          }
        }
      }
    },
    "UPS Mobile (iOs, Android)" : {
      checkbox: false,
      children: {
        "Overview" : {
          checkbox: false,
          ID: 22
        },
        "Reference" : {
          checkbox: false,
          ID: 14
        }
      }
    },
    "mDot" : {
      checkbox: false,
      children: {
        "Elements" : {
          checkbox: false,
          ID: 19,
          children: {
            "Navigation" : {
              checkbox: false,
              ID: 90
            }
          }
        },
      }
    }
  }

I have set up parent and child pages of the above in wordpress and have also created a hierarchical wordpress menu. I am using the wordpress menu api

which returns the following data structure:

[
  {
    "ID": 46,
    "order": 1,
    "parent": 0,
    "title": "Home",
    "attr": "",
    "target": "",
    "classes": "",
    "xfn": "",
    "description": "",
    "object_id": 2,
    "object": "page",
    "type": "post_type",
    "type_label": "Page",
    "children": [
      {
        "ID": 47,
        "order": 2,
        "parent": 46,
        "title": "Getting Started",
        "url": "http://mobilestyle.ups.dev/home/getting-started/",
        "attr": "",
        "target": "",
        "classes": "",
        "xfn": "",
        "description": "",
        "object_id": 15,
        "object": "page",
        "type": "post_type",
        "type_label": "Page",
        "children": []
      },
      {
        "ID": 48,
        "order": 3,
        "parent": 46,
        "title": "Interaction Design Principles",
        "url": "http://mobilestyle.ups.dev/home/interaction-design-principles/",
        "attr": "",
        "target": "",
        "classes": "",
        "xfn": "",
        "description": "",
        "object_id": 22,
        "object": "page",
        "type": "post_type",
        "type_label": "Page",
        "children": [
          {
            "ID": 49,
            "order": 4,
            "parent": 48,
            "title": "Design Principle the First",
            "url": "http://mobilestyle.ups.dev/home/interaction-design-principles/design-principle-the-first/",
            "attr": "",
            "target": "",
            "classes": "",
            "xfn": "",
            "description": "",
            "object_id": 24,
            "object": "page",
            "type": "post_type",
            "type_label": "Page",
            "children": []
          }
        ]
      }
    ]
  },
  {
    "ID": 50,
    "order": 5,
    "parent": 0,
    "title": "mDot",
    "url": "http://mobilestyle.ups.dev/mdot/",
    "attr": "",
    "target": "",
    "classes": "",
    "xfn": "",
    "description": "",
    "object_id": 8,
    "object": "page",
    "type": "post_type",
    "type_label": "Page",
    "children": [
      {
        "ID": 51,
        "order": 6,
        "parent": 50,
        "title": "Elements",
        "url": "http://mobilestyle.ups.dev/mdot/elements/",
        "attr": "",
        "target": "",
        "classes": "",
        "xfn": "",
        "description": "",
        "object_id": 30,
        "object": "page",
        "type": "post_type",
        "type_label": "Page",
        "children": [
          {
            "ID": 52,
            "order": 7,
            "parent": 51,
            "title": "Navigation",
            "url": "http://mobilestyle.ups.dev/mdot/elements/navigation/",
            "attr": "",
            "target": "",
            "classes": "",
            "xfn": "",
            "description": "",
            "object_id": 32,
            "object": "page",
            "type": "post_type",
            "type_label": "Page",
            "children": []
          }
        ]
      }
    ]
  },
  {
    "ID": 54,
    "order": 8,
    "parent": 0,
    "title": "UPS Mobile (iOS, Android)",
    "url": "http://mobilestyle.ups.dev/ups-mobile/",
    "attr": "",
    "target": "",
    "classes": "",
    "xfn": "",
    "description": "",
    "object_id": 13,
    "object": "page",
    "type": "post_type",
    "type_label": "Page",
    "children": [
      {
        "ID": 55,
        "order": 9,
        "parent": 54,
        "title": "Overview",
        "url": "http://mobilestyle.ups.dev/ups-mobile/overview/",
        "attr": "",
        "target": "",
        "classes": "",
        "xfn": "",
        "description": "",
        "object_id": 26,
        "object": "page",
        "type": "post_type",
        "type_label": "Page",
        "children": []
      },
      {
        "ID": 56,
        "order": 10,
        "parent": 54,
        "title": "Reference",
        "url": "http://mobilestyle.ups.dev/ups-mobile/reference/",
        "attr": "",
        "target": "",
        "classes": "",
        "xfn": "",
        "description": "",
        "object_id": 28,
        "object": "page",
        "type": "post_type",
        "type_label": "Page",
        "children": []
      }
    ]
  }
]

Can someone please help me turn what I receive from the wordpress menu api into what the Tree Menu component expects?

Thanks in advance for any help. -Ian

Advertisement

Answer

I’d use a recursive function to build the object you want. Something like the following:

function buildMenu(source, result) {
  //build a return value if one wasn't passed in
  result = result || {};
  
  if (source && source.length) {
    
    var item = source.shift(); //take first item from the array
    result[item.title] = { ID : item.ID }; //make a new property in the result

    //if there are children, build them recursively
    if (item.children && item.children.length) {
      result[item.title].children = buildMenu(item.children);
    }
    
    //build additional items recursively, based on the remaining items in the array
    return buildMenu(source, result);
    
  } else {
    //none left, done
    return result;
  }
}

Call that function on your source array and it should work. There’s a running example below if you want to try it out.

function buildMenu(source, result) {
  result = result || {};
  
  if (source && source.length) {
    
    var item = source.shift();
    result[item.title] = { ID : item.ID };
    
    if (item.children && item.children.length) {
      result[item.title].children = buildMenu(item.children);
    }
    
    return buildMenu(source, result);
    
  } else {
    return result;  
  }
}

var source = [
  {
    "ID": 46,
    "order": 1,
    "parent": 0,
    "title": "Home",
    "attr": "",
    "target": "",
    "classes": "",
    "xfn": "",
    "description": "",
    "object_id": 2,
    "object": "page",
    "type": "post_type",
    "type_label": "Page",
    "children": [
      {
        "ID": 47,
        "order": 2,
        "parent": 46,
        "title": "Getting Started",
        "url": "http://mobilestyle.ups.dev/home/getting-started/",
        "attr": "",
        "target": "",
        "classes": "",
        "xfn": "",
        "description": "",
        "object_id": 15,
        "object": "page",
        "type": "post_type",
        "type_label": "Page",
        "children": []
      },
      {
        "ID": 48,
        "order": 3,
        "parent": 46,
        "title": "Interaction Design Principles",
        "url": "http://mobilestyle.ups.dev/home/interaction-design-principles/",
        "attr": "",
        "target": "",
        "classes": "",
        "xfn": "",
        "description": "",
        "object_id": 22,
        "object": "page",
        "type": "post_type",
        "type_label": "Page",
        "children": [
          {
            "ID": 49,
            "order": 4,
            "parent": 48,
            "title": "Design Principle the First",
            "url": "http://mobilestyle.ups.dev/home/interaction-design-principles/design-principle-the-first/",
            "attr": "",
            "target": "",
            "classes": "",
            "xfn": "",
            "description": "",
            "object_id": 24,
            "object": "page",
            "type": "post_type",
            "type_label": "Page",
            "children": []
          }
        ]
      }
    ]
  },
  {
    "ID": 50,
    "order": 5,
    "parent": 0,
    "title": "mDot",
    "url": "http://mobilestyle.ups.dev/mdot/",
    "attr": "",
    "target": "",
    "classes": "",
    "xfn": "",
    "description": "",
    "object_id": 8,
    "object": "page",
    "type": "post_type",
    "type_label": "Page",
    "children": [
      {
        "ID": 51,
        "order": 6,
        "parent": 50,
        "title": "Elements",
        "url": "http://mobilestyle.ups.dev/mdot/elements/",
        "attr": "",
        "target": "",
        "classes": "",
        "xfn": "",
        "description": "",
        "object_id": 30,
        "object": "page",
        "type": "post_type",
        "type_label": "Page",
        "children": [
          {
            "ID": 52,
            "order": 7,
            "parent": 51,
            "title": "Navigation",
            "url": "http://mobilestyle.ups.dev/mdot/elements/navigation/",
            "attr": "",
            "target": "",
            "classes": "",
            "xfn": "",
            "description": "",
            "object_id": 32,
            "object": "page",
            "type": "post_type",
            "type_label": "Page",
            "children": []
          }
        ]
      }
    ]
  },
  {
    "ID": 54,
    "order": 8,
    "parent": 0,
    "title": "UPS Mobile (iOS, Android)",
    "url": "http://mobilestyle.ups.dev/ups-mobile/",
    "attr": "",
    "target": "",
    "classes": "",
    "xfn": "",
    "description": "",
    "object_id": 13,
    "object": "page",
    "type": "post_type",
    "type_label": "Page",
    "children": [
      {
        "ID": 55,
        "order": 9,
        "parent": 54,
        "title": "Overview",
        "url": "http://mobilestyle.ups.dev/ups-mobile/overview/",
        "attr": "",
        "target": "",
        "classes": "",
        "xfn": "",
        "description": "",
        "object_id": 26,
        "object": "page",
        "type": "post_type",
        "type_label": "Page",
        "children": []
      },
      {
        "ID": 56,
        "order": 10,
        "parent": 54,
        "title": "Reference",
        "url": "http://mobilestyle.ups.dev/ups-mobile/reference/",
        "attr": "",
        "target": "",
        "classes": "",
        "xfn": "",
        "description": "",
        "object_id": 28,
        "object": "page",
        "type": "post_type",
        "type_label": "Page",
        "children": []
      }
    ]
  }
];

var dest = buildMenu(source);
console.log(dest);
User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement