I have a file of JSON-serialized data that looks like this:
{
"name":"Store",
"children":[
{
"name":"Store 1",
"children":[
{
"name":"collection 1",
"description":"collection 1",
"children":[
{
"name":"Products",
"description":"Products",
"children":[
{
"name":"Product 1",
"description":"Product 1"
}
]
}
]
}
],
"description":"category 1"
},
{
"name":"Store 2"
}
]
}
For objects with a name property, I want to add a title whose value is the same as the value of the name property. Below is what I am trying to convert my JSON to:
{
"name":"Store",
"title":"Store",
"children":[
{
"name":"Store 1",
"title":"Store 1",
"children":[
{
"name":"collection 1",
"title":"collection 1",
"description":"collection 1",
"children":[
{
"name":"Products",
"title":"Products",
"description":"Products",
"children":[
{
"name":"Product 1",
"title":"Product 1",
"description":"Product 1"
}
]
}
]
}
],
"description":"category 1"
},
{
"name":"Store 2",
"title":"Store 2"
}
]
}
we can use parse the Json using JSON.Parse and use recursion to add title as below to all the children
function Recursion(items) {
items["title"] = items["name"]
if (items["children"] != undefined) {
items["children"].forEach(element => {
element = Recursion(element)
});
}
return items
}
var text = '{"name":"Store","children":[{"name":"Store 1","children":[{"name":"collection 1","description":"collection 1","children":[{"name":"Products","description":"Products","children":[{"name":"Product 1","description":"Product 1"}]}]}],"description":"category 1"},{"name":"Store 2"}]}';
var item = JSON.parse(text);
item = Recursion(item);
const addTitleRec = (j) => {
j.title = j.name, j.children && j.children.forEach(addTitleRec);
}
const json = {
"name": "Store",
"children": [{
"name": "Store 1",
"children": [{
"name": "collection 1",
"description": "collection 1",
"children": [{
"name": "Products",
"description": "Products",
"children": [{
"name": "Product 1",
"description": "Product 1"
}]
}]
}],
"description": "category 1"
},
{
"name": "Store 2"
}
]
};
addTitleRec(json);
console.log(json);
Related
I have a huge object, with almost 50k lines.
I need to add in each object new key with the current path of the node
Example:
let obj = {
"title": "RESSONÂNCIA MAGNÉTICA DA COLUNA LOMBAR",
"data": [{
"title": "Método:",
"data": [{
"title": "Procedimento 1",
"data": [{
"title": "CONTRASTE"
},
{
"title": "CONTRASTE 2"
}
]
},
{
"title": "Procedimento 2",
"data": [{
"title": "CONTRASTE 3"
},
{
"title": "CONTRASTE 4"
}
]
}
]
}]
}
And I need to change my object to return this:
obj = {
"path": "$",
"title": "RESSONÂNCIA MAGNÉTICA DA COLUNA LOMBAR",
"data": [{
"path": "$.data.0",
"title": "Método:",
"data": [{
"path": "$.data.0.data.0",
"title": "Procedimento 1",
"data": [{
"path": "$.data.0.data.0.data.0",
"title": "CONTRASTE"
},
{
"path": "$.data.0.data.0.data.1",
"title": "CONTRASTE 2"
}
]
},
{
"path": "$.data.0.data.1",
"title": "Procedimento 2",
"data": [{
"path": "$.data.0.data.1.data.0",
"title": "CONTRASTE 3"
},
{
"path": "$.data.0.data.1.data.1",
"title": "CONTRASTE 4"
}
]
}
]
}]
}
If you notice, i added the key path inside each object for key data, with the current path of the node. This is what I need.
All my object are much bigger then this example, with much more nested objects
Performant version in case you have to deal with large files
const data = {
"title": "RESSONÂNCIA MAGNÉTICA DA COLUNA LOMBAR",
"data": [{
"title": "Método:",
"data": [{
"title": "Procedimento 1",
"data": [{
"title": "CONTRASTE"
},
{
"title": "CONTRASTE 2"
}
]
},
{
"title": "Procedimento 2",
"data": [{
"title": "CONTRASTE 3"
},
{
"title": "CONTRASTE 4"
}
]
}
]
}]
}
function PathUpdate(data, path) {
data.path = path;
const nd = data.data;
if (nd == null) return;
for (let i = 0; i < nd.length; i++) {
PathUpdate(nd[i], `${path}.data.${i}`);
}
}
console.log("before", { data });
PathUpdate(data, "$");
console.log("after", { data });
const data = {
title: "RESSONÂNCIA MAGNÉTICA DA COLUNA LOMBAR",
type: "template",
data: [
{
title: "Método:",
type: "top-level-component",
data: [
{
title: "Procedimento",
type: "navigation",
normal: "CONTRASTE",
checked: true,
data: [
{
type: "single-selection",
title: "CONTRASTE",
},
{
type: "single-selection",
title: "CONTRASTE 2",
},
],
},
{
title: "Procedimento 2",
type: "navigation",
normal: "CONTRASTE",
checked: false,
data: [
{
type: "single-selection",
title: "CONTRASTE 3",
},
{
type: "single-selection",
title: "CONTRASTE 4",
},
],
},
],
},
],
};
function addPathToObj(obj, path) {
obj.path = path;
for (const [key, value] of Object.entries(obj)) {
if (Array.isArray(value)) {
value.forEach((item, index) => {
addPathToObj(item, `${path}.data.${index}`);
});
}
}
}
addPathToObj(data, "$");
console.log(data);
{
"name":"123",
"reponsetype":"2",
"ussdcode":"123",
"parrentussd":"0",
"children": [
{
"name":"1 Menu",
"reponsetype":"2",
"ussdcode":"123*1",
"parrentussd":"123"
},
{
"name":"Menu 2",
"reponsetype":"2",
"ussdcode":"123*2",
"parrentussd":"123",
"children":[
{
"name":"Dynamic Menu 1",
"reponsetype":"4",
"ussdcode":"123*2",
"parrentussd":"123*2"
}
]
}
You can do it using recursion.
Try this:
let arr = { "name": "123", "reponsetype": "2", "ussdcode": "123", "parrentussd": "0", "children": [{ "name": "1 Menu", "reponsetype": "2", "ussdcode": "123*1", "parrentussd": "123" }, { "name": "Menu 2", "reponsetype": "2", "ussdcode": "123*2", "parrentussd": "123", "children": [{ "name": "Dynamic Menu 1", "reponsetype": "4", "ussdcode": "123*2", "parrentussd": "123*2" }] }] }
let res = [];
function getChild(obj) {
for (let i = 0; i < obj.children.length; i++) {
if (obj.children[i].children) {
getChild(obj.children[i]);
delete obj.children[i].children;
res.push(obj.children[i])
} else {
res.push(obj.children[i])
}
}
}
getChild(arr);
console.log(res);
I'm trying to loop a complex/nested JSON object. I'm trying to loop var_color.color.primary.
Questions:
What causes this error?
Cannot read property '_id' of undefined
How can I output the primary?
Kindly use only vanilla Javascript.
Example Data
products.json file
{
"products": [
{
"_id": "000",
"name": "Name 1",
"description": "Long description 1"
},
{
"_id": "001",
"name": "Name 2",
"description": "Long description 2",
"var_color": {
"_id": "12341",
"color": {
"primary": "pink",
"secondary": "penk"
}
}
},
{
"_id": "002",
"name": "Name 3",
"description": "Long description 3"
},
{
"_id": "003",
"name": "Name 4",
"description": "Long description 4",
"var_color": {
"_id": "12342",
"color": {
"primary": "red",
"secondary": "rid"
}
}
}
],
"categories": []
}
// main.js
async function getData(product) {
let response = await fetch(`./api/products/${product}`);
let data = await response.json();
return data;
}
getData('products.json').then(data => {
for (let i in data.products) {
let all = data.products[i];
let name = all.name;
let description = all.description;
console.log(name);
console.log(description);
for (let j in all) {
let variantColor = all.var_color[j].primary;
console.log(variantColor);
}
}
});
This is my current script as of the moment.
all.var_color does not exist in each entry, therefore you need to check for its presence.
You are treating all.var_color[j] as if it were an array, but it is an object.
To get the primary color, replace the inner loop (for (let j in all)) with a simple test:
if(all.var_color) {
let variantColor = all.var_color.color.primary;
console.log(variantColor);
}
var data = {
"products": [
{
"_id": "000",
"name": "Name 1",
"description": "Long description 1"
},
{
"_id": "001",
"name": "Name 2",
"description": "Long description 2",
"var_color": {
"_id": "12341",
"color": {
"primary": "pink",
"secondary": "penk"
}
}
},
{
"_id": "002",
"name": "Name 3",
"description": "Long description 3"
},
{
"_id": "003",
"name": "Name 4",
"description": "Long description 4",
"var_color": {
"_id": "12342",
"color": {
"primary": "red",
"secondary": "rid"
}
}
}
],
"categories": []
};
for (let i in data.products) {
let all = data.products[i];
let name = all.name;
let description = all.description;
console.log(name);
console.log(description);
if(all.var_color) {
let variantColor = all.var_color.color.primary;
console.log(variantColor);
}
}
Given a data structure like so:
"items":
{
"Groups":[
{
"title":"group 1",
"SubGroups":[
{
"title":"sub1",
"id" : "1",
"items":[
{
"title":"Ajax request 1",
},
{
"title":"Ajax request 2",
}
]
},
{
"title":"sub2",
"id" : "2",
"items":[
{
"title":"Ajax request 3",
},
{
"title":"Ajax request 4",
}
]
}
]
}
]
How can I pull out all the items for a sub group based on the id? Ive treid using find like so:
var res1 = _.where(listing.items,{id:"2"});
but get an empty array returned
Thanks
Try targeting the subgroups array and then search for the id you want in there. That should then return the properties for that subgroup.
var obj = {
"Groups": [{
"title": "group 1",
"SubGroups": [{
"title": "sub1",
"id": "1",
"items": [{
"title": "Ajax request 1",
}, {
"title": "Ajax request 2",
}]
}, {
"title": "sub2",
"id": "2",
"items": [{
"title": "Ajax request 3",
}, {
"title": "Ajax request 4",
}]
}]
}]
}
then find values like this
_.where(obj.Groups[0].SubGroups, {
'id': '2'
});
Just tested and this seems to work
{
"data": [{
"prop": "prop1",
"template": "template1",
"group": [{
"group_name": "Group 1",
}, {
"group_name": "Group 2",
}, {
"group_name": "Group 3",
}]
}]
}
In the above json I need push the group_no based on group_name. i.e. If group_name is equal to Group 1 then group_no is equal to 10. and form the following json. How do I update the existing json?
{
"data": [{
"prop": "prop1",
"template": "template1",
"group": [{
"group_name": "Group 1",
"group_no": "10"
}, {
"group_name": "Group 2",
"group_no": "11"
}, {
"group_name": "Group 3",
"group_no": "12"
}]
}]
}
Do it this way.
var json = {
"data": [{
"prop": "prop1",
"template": "template1",
"group": [{
"group_name": "Group 1",
}, {
"group_name": "Group 2",
}, {
"group_name": "Group 3",
}]
}]
};
json.data[0].group.forEach(function(d){
if(d.group_name=="Group 1")
d.group_no = 10;
else if(d.group_name=="Group 2")
d.group_no = 11;
else
d.group_no = 12;
});
alert(JSON.stringify(json));
Not sure what you mean by not looping, for you need to loop through it anyway. But what you want is done like this:
data[0].group = data[0].group.map(function(el) {
switch (el.group_name) {
case 'Group 1': return el.group_no = '10';
case 'Group 2': return el.group_no = '11';
...
default: return el;
}
});
If your JSON object is actually text, you first to var parsed = JSON.parse(data); and work with parsed instead of data. Afterwords you can data = JSON.stringify(parsed);