How to push object array into array with key - javascript

This is my main data: (this.data)
{
"id": 7,
"name": "Revenue",
"characterCount": 1,
"maxLevel": 4,
"individualCode": "1",
"combinedCode": "02-1",
"isActive": true,
"topLevelId": 2,
"topLevelChildCount": 1,
"parentId": 2,
},
{
"id": 8,
"name": "Revenue1",
"characterCount": 1,
"maxLevel": 4,
"individualCode": "1",
"combinedCode": "02-1",
"isActive": true,
"topLevelId": 2,
"topLevelChildCount": 1,
"parentId": 2,
},
I have one child data: this.childData
{
"id": 14,
"name": "Sales",
"characterCount": 1,
"maxLevel": 2,
"individualCode": "1",
"combinedCode": "02-1-1",
"isActive": true,
"topLevelId": 2,
"topLevelChildCount": 0,
"parentId": 7
},
{
"id": 15,
"name": "Sales1",
"characterCount": 1,
"maxLevel": 2,
"individualCode": "1",
"combinedCode": "02-1-1",
"isActive": true,
"topLevelId": 2,
"topLevelChildCount": 0,
"parentId": 7
}
I want to push this childData in main this.data at specific index for eg index 0,with key "child"
means my data should look like this:
{
"id": 7,
"name": "Revenue",
"characterCount": 1,
"maxLevel": 4,
"individualCode": "1",
"combinedCode": "02-1",
"isActive": true,
"topLevelId": 2,
"topLevelChildCount": 1,
"parentId": 2,
"child": [
{
"id": 14,
"name": "Sales",
"characterCount": 1,
"maxLevel": 2,
"individualCode": "1",
"combinedCode": "02-1-1",
"isActive": true,
"topLevelId": 2,
"topLevelChildCount": 0,
"parentId": 7
},
{
"id": 15,
"name": "Sales1",
"characterCount": 1,
"maxLevel": 2,
"individualCode": "1",
"combinedCode": "02-1-1",
"isActive": true,
"topLevelId": 2,
"topLevelChildCount": 0,
"parentId": 7
}
]
},
{
"id": 8,
"name": "Revenue1",
"characterCount": 1,
"maxLevel": 4,
"individualCode": "1",
"combinedCode": "02-1",
"isActive": true,
"topLevelId": 2,
"topLevelChildCount": 1,
"parentId": 2,
},
}
I tried this this.data[index].push(this.childData);
but didnt worked for me. Is there any method so that i can achieve this?
getChildData(id,index)
{
console.log('id',id);
console.log('index',index);
const params ={};
params['parentId'] = id;
this.jvLedgerReportService.getMonthlyActivityReport(params).subscribe(data => {
this.childData = data.items
console.log("childData",this.childData);
this.data[index].push(this.childData);
console.log("after",this.data);
})
}

this.data[index]['child'] = this.childData;
OR
this.data[index].child = this.childData;

Create a "child" array key and push child data to it
var parent = [];
parent.push({
"id": 7,
"name": "Revenue",
"characterCount": 1,
"maxLevel": 4,
"individualCode": "1",
"combinedCode": "02-1",
"isActive": true,
"topLevelId": 2,
"topLevelChildCount": 1,
"parentId": 2,
"child":[]
});
parent.push({
"id": 8,
"name": "Revenue1",
"characterCount": 1,
"maxLevel": 4,
"individualCode": "1",
"combinedCode": "02-1",
"isActive": true,
"topLevelId": 2,
"topLevelChildCount": 1,
"parentId": 2,
"child":[]
});
var childData = [{
"id": 14,
"name": "Sales",
"characterCount": 1,
"maxLevel": 2,
"individualCode": "1",
"combinedCode": "02-1-1",
"isActive": true,
"topLevelId": 2,
"topLevelChildCount": 0,
"parentId": 7
},
{
"id": 15,
"name": "Sales1",
"characterCount": 1,
"maxLevel": 2,
"individualCode": "1",
"combinedCode": "02-1-1",
"isActive": true,
"topLevelId": 2,
"topLevelChildCount": 0,
"parentId": 7
}];
parent[0].child.push(childData);
console.log(parent);

var parent = [{
"id": 7,
"name": "Revenue",
"parentId": 2,
},
{
"id": 8,
"name": "Revenue1",
"parentId": 2,
}];
var child = [{
"id": 11,
"name": "Revenue",
"parentId": 7,
},
{
"id": 81,
"name": "Revenue1",
"parentId": 7,
}];
var result = parent.map(x=> {
var childData = child.filter(y=>y.parentId==x.id);
debugger;
if (childData && childData.length >0) {
x['child'] = childData;
}
return x;
});
console.log(result);
Loop throgh parent records and match the ID with child records. If it finds the records then add it into you main records as a Child property and store the data.

// Solution using callbacks
const traverse = (data, callback) => {
const visit = (node) => {
callback(node);
node.child.forEach((child) => visit(child));
}
visit(data);
}
const add = (yourData, dataToAdd, parentId) => {
traverse(yourData, (node) => {
if (node.id === parentId) {
if (!node.child) {
node.child = [...dataToAdd];
} else {
node.child = [...node.child, ...dataToAdd];
}
}
})
}
Then just call add i.e
add(this.data, this.childData, parentId);

You can achieve that like this if you want to merge the arrays using parentId:
const data = [{
"id": 7,
"name": "Revenue",
"characterCount": 1,
"maxLevel": 4,
"individualCode": "1",
"combinedCode": "02-1",
"isActive": true,
"topLevelId": 2,
"topLevelChildCount": 1,
"parentId": 2,
},
{
"id": 8,
"name": "Revenue1",
"characterCount": 1,
"maxLevel": 4,
"individualCode": "1",
"combinedCode": "02-1",
"isActive": true,
"topLevelId": 2,
"topLevelChildCount": 1,
"parentId": 2,
}
];
const childData = [{
"id": 14,
"name": "Sales",
"characterCount": 1,
"maxLevel": 2,
"individualCode": "1",
"combinedCode": "02-1-1",
"isActive": true,
"topLevelId": 2,
"topLevelChildCount": 0,
"parentId": 7
},
{
"id": 15,
"name": "Sales1",
"characterCount": 1,
"maxLevel": 2,
"individualCode": "1",
"combinedCode": "02-1-1",
"isActive": true,
"topLevelId": 2,
"topLevelChildCount": 0,
"parentId": 7
}
];
const result = data.map((item) => {
const childArr = [];
childData.forEach((childItem) => {
if (item.id === childItem.parentId) {
childArr.push(childItem);
}
});
if (childArr.length > 0) {
item.child = childArr
}
return item;
});
console.log(result);

interface my_data {
[key: string]: any;
}
data: my_data {
//your data here
}
childData {
//your data here
}
this.data[index]['child'] = this.childData

Related

Array object grouping in JavaScript

I need to convert below unformatted JSON format into formatted input. We need to find id's similar to parent id for different items inside array element of object and then need to push it into children to that id. Below is my code that needs to transform
Input
{
"0": [
{
"id": 10,
"title": "House",
"level": 0,
"children": [],
"parent_id": null
}
],
"1": [
{
"id": 12,
"title": "Red Roof",
"level": 1,
"children": [],
"parent_id": 10
},
{
"id": 18,
"title": "Blue Roof",
"level": 1,
"children": [],
"parent_id": 10
}
],
"2": [
{
"id": 17,
"title": "Blue Windoww",
"level": 2,
"children": [],
"parent_id": 12
},
{
"id": 16,
"title": "Door",
"level": 2,
"children": [],
"parent_id": 13
}
]
}
Output
[
{
"id": 10,
"title": "House",
"level": 0,
"children": [
{
"id": 12,
"title": "RedRoofff",
"level": 1,
"children": [
{
"id": 17,
"title": "Blue Windoww",
"level": 2,
"children": [],
"parent_id": 12
}
],
"parent_id": 10
},
{
"id": 18,
"title": "Blue Roof",
"level": 1,
"children": [],
"parent_id": 10
},
{
"id": 13,
"title": "Wall",
"level": 1,
"children": [
{
"id": 16,
"title": "Door",
"level": 2,
"children": [],
"parent_id": 13
}
],
"parent_id": 10
}
],
"parent_id": null
}
]
Please find the solution to above problem.
first, we track the node with Id and then we update the children array like this.
(btw, your input have a missing node, 13)
const input = {
"0": [{
"id": 10,
"title": "House",
"level": 0,
"children": [],
"parent_id": null
}, {
"id": 13,
"title": "Wall",
"level": 0,
"children": [],
"parent_id": null
}],
"1": [{
"id": 12,
"title": "Red Roof",
"level": 1,
"children": [],
"parent_id": 10
},
{
"id": 18,
"title": "Blue Roof",
"level": 1,
"children": [],
"parent_id": 10
},
],
"2": [{
"id": 17,
"title": "Blue Windoww",
"level": 2,
"children": [],
"parent_id": 12
},
{
"id": 16,
"title": "Door",
"level": 2,
"children": [],
"parent_id": 13
},
]
};
const results = [];
const mapId2Node = Object.values(input).reduce((acc, vals) => {
vals.forEach(val => {
acc[val.id] = val;
if (val.parent_id === null) {
results.push(val);
}
});
return acc;
}, {});
Object.values(input).forEach(vals => {
vals.forEach(val => {
if (val.parent_id !== null) {
mapId2Node[val.parent_id].children.push(val);
}
});
});
conosle.log(results);

How to remove all empty array childrens [] from a nested JSON recursively [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I've a JSON response as below.I'm using nested JSON data from my GeoRegionCountries APIController & custom class TreeView is used to format the data as per the required nested structure of plugin I'm using. I am using a combo multi select Treeview using this jquery plugin Multi-Select Drop Down Tree Plugin you can see it by this link jquery plugin Multi-Select Drop Down Tree Plugin
[
{
"Id": 1,
"Title": "United States",
"ParentId": null,
"Subs": [
{
"Id": 7,
"Title": "Northwest",
"ParentId": 1,
"Subs": []
},
{
"Id": 8,
"Title": "Northeast",
"ParentId": 1,
"Subs": []
},
{
"Id": 9,
"Title": "Central",
"ParentId": 1,
"Subs": []
},
{
"Id": 10,
"Title": "Southwest",
"ParentId": 1,
"Subs": []
},
{
"Id": 18,
"Title": "Southeast",
"ParentId": 1,
"Subs": []
}
]
},
{
"Id": 2,
"Title": "Canada",
"ParentId": null,
"Subs": []
},
{
"Id": 3,
"Title": "France",
"ParentId": null,
"Subs": []
},
{
"Id": 4,
"Title": "Germany",
"ParentId": null,
"Subs": []
},
{
"Id": 5,
"Title": "Australia",
"ParentId": null,
"Subs": []
},
{
"Id": 6,
"Title": "United Kingdom",
"ParentId": null,
"Subs": []
}
]
I want to remove all "Subs" with empty array.
[
{
"Id": 1,
"Title": "United States",
"ParentId": null,
"Subs": [
{
"Id": 7,
"Title": "Northwest",
"ParentId": 1
},
{
"Id": 8,
"Title": "Northeast",
"ParentId": 1
},
{
"Id": 9,
"Title": "Central",
"ParentId": 1
},
{
"Id": 10,
"Title": "Southwest",
"ParentId": 1
},
{
"Id": 18,
"Title": "Southeast",
"ParentId": 1
}
]
},
{
"Id": 2,
"Title": "Canada",
"ParentId": null
},
{
"Id": 3,
"Title": "France",
"ParentId": null
},
{
"Id": 4,
"Title": "Germany",
"ParentId": null
},
{
"Id": 5,
"Title": "Australia",
"ParentId": null
},
{
"Id": 6,
"Title": "United Kingdom",
"ParentId": null
}
]
What is the best way to deep clean this? I tried different solutions in Stackopverflow but all i got is Object object in place of empty Subs - which i don't want.
[
{
"Id": 1,
"Title": "United States",
"ParentId": null,
"Subs": [
{
"Id": 7,
"Title": "Northwest",
"ParentId": 1,
Object object
},
{
"Id": 8,
"Title": "Northeast",
"ParentId": 1,
Object object
},
{
"Id": 9,
"Title": "Central",
"ParentId": 1,
Object object
},
{
"Id": 10,
"Title": "Southwest",
"ParentId": 1,
Object object
},
{
"Id": 18,
"Title": "Southeast",
"ParentId": 1,
Object object
}
]
},
{
"Id": 2,
"Title": "Canada",
"ParentId": null,
Object object
},
{
"Id": 3,
"Title": "France",
"ParentId": null,
Object object
},
{
"Id": 4,
"Title": "Germany",
"ParentId": null,
Object object
},
{
"Id": 5,
"Title": "Australia",
"ParentId": null,
Object object
},
{
"Id": 6,
"Title": "United Kingdom",
"ParentId": null,
Object object
}
]
which is not i want
You can use _.transform() to recursively check for a specific key (Subs), and remove it if it's value is empty:
const { transform, isObject, isEmpty } = _;
const removeEmpty = (obj, key) =>
transform(obj, (r, v, k) => {
if(k === key && isEmpty(v)) return;
r[k] = isObject(v) ? removeEmpty(v, key) : v;
});
const tree = [{"Id":1,"Title":"United States","ParentId":null,"Subs":[{"Id":7,"Title":"Northwest","ParentId":1,"Subs":[]},{"Id":8,"Title":"Northeast","ParentId":1,"Subs":[]},{"Id":9,"Title":"Central","ParentId":1,"Subs":[]},{"Id":10,"Title":"Southwest","ParentId":1,"Subs":[]},{"Id":18,"Title":"Southeast","ParentId":1,"Subs":[]}]},{"Id":2,"Title":"Canada","ParentId":null,"Subs":[]},{"Id":3,"Title":"France","ParentId":null,"Subs":[]},{"Id":4,"Title":"Germany","ParentId":null,"Subs":[]},{"Id":5,"Title":"Australia","ParentId":null,"Subs":[]},{"Id":6,"Title":"United Kingdom","ParentId":null,"Subs":[]}]
const result = removeEmpty(tree, 'Subs');
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>
The correct answer would be this:
let array = [
{
'Id': 1,
'Title': 'United States',
'ParentId': null,
'Subs': [
{
'Id': 7,
'Title': 'Northwest',
'ParentId': 1,
'Subs': []
},
{
'Id': 8,
'Title': 'Northeast',
'ParentId': 1,
'Subs': []
},
{
'Id': 9,
'Title': 'Central',
'ParentId': 1,
'Subs': []
},
{
'Id': 10,
'Title': 'Southwest',
'ParentId': 1,
'Subs': []
},
{
'Id': 18,
'Title': 'Southeast',
'ParentId': 1,
'Subs': []
}
]
},
{
'Id': 2,
'Title': 'Canada',
'ParentId': null,
'Subs': []
},
{
'Id': 3,
'Title': 'France',
'ParentId': null,
'Subs': []
},
{
'Id': 4,
'Title': 'Germany',
'ParentId': null,
'Subs': []
},
{
'Id': 5,
'Title': 'Australia',
'ParentId': null,
'Subs': []
},
{
'Id': 6,
'Title': 'United Kingdom',
'ParentId': null,
'Subs': []
}
]
let newArray = array.map(item=> {
if (item.Subs.length===0){
delete item.Subs
return item
}
item.Subs = item.Subs.map(item=>{
if (item.Subs.length===0){
delete item.Subs
return item
}
})
return item
}
)
console.log(newArray)
let data = [
{
"Id": 1,
"Title": "United States",
"ParentId": null,
"Subs": [
{
"Id": 7,
"Title": "Northwest",
"ParentId": 1,
"Subs": []
},
{
"Id": 8,
"Title": "Northeast",
"ParentId": 1,
"Subs": []
},
{
"Id": 9,
"Title": "Central",
"ParentId": 1,
"Subs": []
},
{
"Id": 10,
"Title": "Southwest",
"ParentId": 1,
"Subs": []
},
{
"Id": 18,
"Title": "Southeast",
"ParentId": 1,
"Subs": []
}
]
},
{
"Id": 2,
"Title": "Canada",
"ParentId": null,
"Subs": []
},
{
"Id": 3,
"Title": "France",
"ParentId": null,
"Subs": []
},
{
"Id": 4,
"Title": "Germany",
"ParentId": null,
"Subs": []
},
{
"Id": 5,
"Title": "Australia",
"ParentId": null,
"Subs": []
},
{
"Id": 6,
"Title": "United Kingdom",
"ParentId": null,
"Subs": []
}
];
data = data.map(row=>{
if (!row.Subs.length) {
let {Subs,...r} = row;
return r;
} return row
})
console.log(data);
write two functions and pass the function that iterates through your array to a map function on data as shown below
function formatData(val) {
if (val.Subs.length > 0) val.Subs.map(a => a.Subs.length > 0 ? formatData(a.Subs) : deleteSubs(a));
else deleteSubs(val);
return val;
}
function deleteSubs(val) {
delete val.Subs;
}
var data = [{
"Id": 1,
"Title": "United States",
"ParentId": null,
"Subs": [{
"Id": 7,
"Title": "Northwest",
"ParentId": 1,
"Subs": []
},
{
"Id": 8,
"Title": "Northeast",
"ParentId": 1,
"Subs": []
},
{
"Id": 9,
"Title": "Central",
"ParentId": 1,
"Subs": []
},
{
"Id": 10,
"Title": "Southwest",
"ParentId": 1,
"Subs": []
},
{
"Id": 18,
"Title": "Southeast",
"ParentId": 1,
"Subs": []
}
]
},
{
"Id": 2,
"Title": "Canada",
"ParentId": null,
"Subs": []
},
{
"Id": 3,
"Title": "France",
"ParentId": null,
"Subs": []
},
{
"Id": 4,
"Title": "Germany",
"ParentId": null,
"Subs": []
},
{
"Id": 5,
"Title": "Australia",
"ParentId": null,
"Subs": []
},
{
"Id": 6,
"Title": "United Kingdom",
"ParentId": null,
"Subs": []
}
]
console.log(data.map(formatData))

finding a value belongs to array or not in javascript

I have following JavaScript Array
business: [{
"id": 22,
"name": "Private",
"max_mem": 0,
"gen_roomtype_id": 4,
"status": 1,
"type": 0,
"set_value": 1
},
{
"id": 6,
"name": "Standard ward",
"max_mem": 0,
"gen_roomtype_id": 2,
"status": 1,
"type": 0,
"set_value": 1
},
{
"id": 7,
"name": "Semi Private",
"max_mem": 0,
"gen_roomtype_id": 3,
"status": 1,
"type": 0,
"set_value": 1
}],
"gen": [{
"id": 5,
"name": "laboratory",
"description": "",
"sharing": 0,
"set_value": 2
}],
And i have a idArray as following
idArray: [5, 7]
i would like to know whether the idArray values are belongs to "gen" Array or
"business" Array.
You can use the function every
This approach assumes the input data is an object.
var obj = { business: [{ "id": 5, "name": "Private", "max_mem": 0, "gen_roomtype_id": 4, "status": 1, "type": 0, "set_value": 1 }, { "id": 6, "name": "Standard ward", "max_mem": 0, "gen_roomtype_id": 2, "status": 1, "type": 0, "set_value": 1 }, { "id": 7, "name": "Semi Private", "max_mem": 0, "gen_roomtype_id": 3, "status": 1, "type": 0, "set_value": 1 } ], "gen": [{ "id": 5, "name": "laboratory", "description": "", "sharing": 0, "set_value": 2 }]
};
var idArray = [5, 7];
var resultBusiness = idArray.every(n => obj.business.some(b => b.id === n));
var resultGen = idArray.every(n => obj.gen.some(b => b.id === n));
console.log("All in business: ", resultBusiness);
console.log("All in Gen: ", resultGen);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Javascript sort array with last item created

I want to sort my arrays using this below condition
My json object:
[
{
"id": 1,
"status": true,
"time": "2018-03-05T10:24:15.000Z",
"complaintId": 1
},
{
"id": 2,
"status": true,
"time": null,
"complaintId": 1
},
{
"id": 3,
"status": true,
"time": "2018-03-05T10:53:14.000Z",
"complaintId": 2
},
{
"id": 6,
"status": false,
"time": "2018-03-05T11:58:45.000Z",
"complaintId": 1
},
{
"id": 7,
"status": true,
"time": "2018-03-05T12:11:53.000Z",
"complaintId": 1
},
{
"id": 8,
"status": false,
"time": "2018-03-05T13:23:13.000Z",
"complaintId": 2
},
{
"id": 9,
"status": true,
"time": "2018-03-05T08:17:18.000Z",
"complaintId": 3
},
{
"id": 10,
"status": true,
"time": "2018-03-05T12:32:08.000Z",
"complaintId": 2
}
]
I have complaintId in my json,
i need to get json object of times with complaintId which located in last, for example there are many complaintId:1 in object.
i need to get only which have complaintId in last.
My expected output:
[
{
"id": 7,
"status": true,
"time": "2018-03-05T12:11:53.000Z",
"complaintId": 1
},
{
"id": 9,
"status": true,
"time": "2018-03-05T08:17:18.000Z",
"complaintId": 3
},
{
"id": 10,
"status": true,
"time": "2018-03-05T12:32:08.000Z",
"complaintId": 2
}
]
You can use array#reduce and for each type of complaintId check if it doesn't time value, then update it or if the object has time value and then update the value corresponding to that complaintId.
var data = [ { "id": 1, "status": true, "time": "2018-03-05T10:24:15.000Z", "complaintId": 1 }, { "id": 2, "status": true, "time": null, "complaintId": 1 }, { "id": 3, "status": true, "time": "2018-03-05T10:53:14.000Z", "complaintId": 2 }, { "id": 6, "status": false,"time": "2018-03-05T11:58:45.000Z", "complaintId": 1 }, { "id": 7, "status": true, "time": "2018-03-05T12:11:53.000Z", "complaintId": 1 }, { "id": 8, "status": false, "time": "2018-03-05T13:23:13.000Z", "complaintId": 2 }, { "id": 9, "status": true, "time":"2018-03-05T08:17:18.000Z", "complaintId": 3 }, { "id": 10, "status": true, "time": "2018-03-05T12:32:08.000Z", "complaintId": 2 } ],
result = Object.values(data.reduce((r,o) => {
if(!r[o.complaintId] || !r[o.complaintId].time || o.time)
r[o.complaintId] = {...o};
return r;
},{}))
.sort((a,b) => a.id - b.id);
console.log(result);

Iterating over hierachical nested data and building html from it

I'm a bit mentally stuck in processing some data in JS with that I'm outputting from my API.
What the backend is outputing is a category list that can be nested up to N-th level.
What I'm trying to do is generate a nice nested structure for them so that they represent the JSON structure but in the DOM:
<div>
Women's Fashion
<div>
Women's Clothes
<div>Dresses</div>
<div>Watches</div>
<div>Etc.</div>
</div>
<div>
Watches
</div>
<div>
Jewellery
<div>Swarowski</div>
<div>Other</div>
</div>
</div>
What's a good way for me to achieve this structure?
Here is a sample of the data I'm outputing. The key stuff here is that each Category can have a M-number of subcategories and the end-depth is not actually limited.
{
"results": [
{
"id": 1,
"name": "Women's Fashion",
"hashtag": "#womensfashion",
"parent_id": null,
"parents_list": [],
"product_count": 9466,
"subcategories": [
{
"id": 2,
"name": "Womens Clothes",
"hashtag": "#womensclothes",
"parent_id": 1,
"parents_list": [
1
],
"product_count": 2940,
"subcategories": [
{
"id": 3,
"name": "Dresses",
"hashtag": "#dresses",
"parent_id": 2,
"parents_list": [
2,
1
],
"product_count": null,
"subcategories": []
},
{
"id": 4,
"name": "Tops",
"hashtag": "#womenstops",
"parent_id": 2,
"parents_list": [
2,
1
],
"product_count": null,
"subcategories": []
},
{
"id": 5,
"name": "Outwear",
"hashtag": "#womensoutwear",
"parent_id": 2,
"parents_list": [
2,
1
],
"product_count": null,
"subcategories": []
},
{
"id": 6,
"name": "Shirts",
"hashtag": "#womensshirts",
"parent_id": 2,
"parents_list": [
2,
1
],
"product_count": null,
"subcategories": []
},
{
"id": 7,
"name": "Pants and Shorts",
"hashtag": "#womenspantsandshorts",
"parent_id": 2,
"parents_list": [
2,
1
],
"product_count": null,
"subcategories": []
},
{
"id": 8,
"name": "Skirts",
"hashtag": "#skirts",
"parent_id": 2,
"parents_list": [
2,
1
],
"product_count": null,
"subcategories": []
},
{
"id": 9,
"name": "Jeans",
"hashtag": "#womensjeans",
"parent_id": 2,
"parents_list": [
2,
1
],
"product_count": null,
"subcategories": []
},
{
"id": 10,
"name": "Lingerie and Nightweare",
"hashtag": "#lingerieandnightweare",
"parent_id": 2,
"parents_list": [
2,
1
],
"product_count": null,
"subcategories": []
},
{
"id": 12,
"name": "Muslimawear",
"hashtag": "#womensmuslimawear",
"parent_id": 2,
"parents_list": [
2,
1
],
"product_count": null,
"subcategories": []
},
{
"id": 109,
"name": "Other Womensclothes",
"hashtag": "#otherwomensclothes",
"parent_id": 2,
"parents_list": [
2,
1
],
"product_count": null,
"subcategories": []
},
{
"id": 135,
"name": "Sweaters and Jackets",
"hashtag": "#womenssweatersandjackets",
"parent_id": 2,
"parents_list": [
2,
1
],
"product_count": null,
"subcategories": []
}
]
},
{
"id": 15,
"name": "Bags, Purses and Wallets",
"hashtag": "#womensbags",
"parent_id": 1,
"parents_list": [
1
],
"product_count": 1626,
"subcategories": []
},
{
"id": 16,
"name": "Shoes",
"hashtag": "#womensshoes",
"parent_id": 1,
"parents_list": [
1
],
"product_count": 811,
"subcategories": []
},
{
"id": 19,
"name": "Watches",
"hashtag": "#womenswatches",
"parent_id": 1,
"parents_list": [
1
],
"product_count": 513,
"subcategories": []
},
{
"id": 17,
"name": "Eyewear",
"hashtag": "#womenseyewear",
"parent_id": 1,
"parents_list": [
1
],
"product_count": 145,
"subcategories": []
},
{
"id": 18,
"name": "Jewellery",
"hashtag": "#womensjewellery",
"parent_id": 1,
"parents_list": [
1
],
"product_count": 289,
"subcategories": []
},
{
"id": 110,
"name": "Other Womensfashion",
"hashtag": "#otherwomensfashion",
"parent_id": 1,
"parents_list": [
1
],
"product_count": 129,
"subcategories": []
}
]
}
]
}
What I'm thinking I need to do here is declare a function which goes over a tier and returns everything. Like
process_category(category)
{
let html = [];
for(var i = 0; i < category.length; i++)
{
let nested_html = null;
if(i.subcategories.length > 0)
{
nested_html = process_category(i.subcategories);
}
let new_html = [
<ListItem
primaryText={i.name}
onTouchTap={this.click_category.bind(this, i.id)}
nestedItems={[nested_html]}
/>
];
html = [...html, ...new_html];
}
return(html);
}
EDIT:
Feeling incredibly stupud for not realizing how Javascript for/each works (was writing a python for x in categories: print x.name)
The fixed code which works but I'm not sure is optimal:
process_category(category)
{
let html = [];
for(var i in category)
{
let nested_html = null;
if(category[i].subcategories.length > 0)
{
nested_html = this.process_category(category[i].subcategories);
}
let new_html = [
<ListItem
primaryText={category[i].name}
// onTouchTap={this.click_category.bind(this, category[i].id)}
nestedItems={nested_html}
/>
];
html = [...html, ...new_html];
}
return(html);
}
I would recommend recursion:
function generateDom(obj) {
var node = document.createElement("div");
var textnode = document.createTextNode(obj.name);
node.appendChild(textnode);
for (var i in obj.subcategories) {
var subcategory = obj.subcategories[i];
node.append(generateDom(subcategory));
}
return node;
}
Working example: https://jsfiddle.net/mspinks/fdk2m2ua/
Here's a reactjs based fiddle that may get you in the right direction: https://jsfiddle.net/giladaya/yo4xa3z1/4/
Main thing to note is the use of a recursive component:
const Item = function(props) {
let { data } = props
let children
if (data.subcategories.length > 0) {
children = (
<div className={`level-${props.level}`}>
{data.subcategories.map((item, idx) =>
<Item data={item} level={props.level+1} key={`item-${idx}`}/>
)}
</div>
)
} else {
children = null
}
return (
<div>
{data.name}
{children}
</div>
)
}

Categories