Add parameter to json based on existing parameter value - javascript

{
"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);

Related

Adding data to a nested JSON object with children based on an array - Javascript/REACT

Hello stackoverflow community! I've been creating my own fullstack application for a while now, on the NEXTjs framework. This is going pretty well!! Unfortunately, I got stuck on a JSON import object for a treeview component. The treeview component must be populated using a specific nested structure, along with which treeview item should be selected on an initial render.
I managed to get the correct JSON object from the database, using a sql recursive tree function.
const jsonObject =
{
"id": "bfa3fdf8-4672-404e-baf5-0f9098a5705b",
"label": "main category 1",
"children": [
{
"id": "12e544bc-91b1-4e5d-bdbc-2163a5618305",
"label": "sub category 1.1",
"children": []
},
{
"id": "3f5e5cc7-f8b2-4d75-89e1-841c66d863e6",
"label": "sub category 1.2",
"children": [
{
"id": "903a727f-d94d-44ff-b2f6-a985fd167343",
"label": "sub category 1.2.1",
"children": []
},
{
"id": "fb344480-8588-4ce3-9662-f8e89069e4b4",
"label": "sub category 1.2.2",
"children": []
}
]
}
]
}
The problem is that this object, with categories needs to be updated with a 'checked: "true"' or 'checked: "false"' key value pair based on the existence in the referenceSelectedCategories array. And I don't know how to do this; maintaining the structure and object as needed.
const desiredOutputJsonObject =
{
"id": "bfa3fdf8-4672-404e-baf5-0f9098a5705b",
"label": "main category 1",
** "checked": "false",**
"children": [
{
"id": "12e544bc-91b1-4e5d-bdbc-2163a5618305",
"label": "sub category 1.1",
** "checked": "true",**
"children": []
},
{
"id": "3f5e5cc7-f8b2-4d75-89e1-841c66d863e6",
"label": "sub category 1.2",
** "checked": "false",**
"children": [
{
"id": "903a727f-d94d-44ff-b2f6-a985fd167343",
"label": "sub category 1.2.1",
** "checked": "false",**
"children": []
},
{
"id": "fb344480-8588-4ce3-9662-f8e89069e4b4",
"label": "sub category 1.2.2",
** "checked": "true",**
"children": []
}
]
}
]
}
const referenceSelectedCategories =
[
{
"categoryId": "12e544bc-91b1-4e5d-bdbc-2163a5618305",
"productId": "efed1c38-391b-4b5a-a9f1-91f3faec5f44",
"Id": "f82b0f63-3f39-486c-9157-5c7683b8e3b2"
},
{
"categoryId": "fb344480-8588-4ce3-9662-f8e89069e4b4",
"productId": "efed1c38-391b-4b5a-a9f1-91f3faec5f44",
"Id": "b2e8681b-eec4-404d-8f87-c6314db42e30"
}
]
I've read several stackoverflow questions, also searched for examples, but can't get it to work. Could someone help me out here?
Some extra information:
Code language I'm using is REACT on NEXTjs framework;
Treeview component could have a dept of max 5 levels;
The structure of the JSON object doesn't change, it's exactly as presented above.
The "id" in the JSON object corresponds to the "categoryId" in the array.
Do you need more information? :) Just ask, I'll provide you with the extra details!
Kind Regards,
Chris
A straight forward solution with recursive method. Done a quick test, working fine. If any issues found, please point it out.
const parentObj =
[
{
"categoryId": "12e544bc-91b1-4e5d-bdbc-2163a5618305",
"productId": "efed1c38-391b-4b5a-a9f1-91f3faec5f44",
"Id": "f82b0f63-3f39-486c-9157-5c7683b8e3b2"
},
{
"categoryId": "fb344480-8588-4ce3-9662-f8e89069e4b4",
"productId": "efed1c38-391b-4b5a-a9f1-91f3faec5f44",
"Id": "b2e8681b-eec4-404d-8f87-c6314db42e30"
}
]
const existingId = parentObj.map((item)=> (item.Id))
const childobj =
{
"id": "bfa3fdf8-4672-404e-baf5-0f9098a5705b",
"label": "main category 1",
"children": [
{
"id": "12e544bc-91b1-4e5d-bdbc-2163a5618305",
"label": "sub category 1.1",
"children": []
},
{
"id": "3f5e5cc7-f8b2-4d75-89e1-841c66d863e6",
"label": "sub category 1.2",
"children": [
{
"id": "903a727f-d94d-44ff-b2f6-a985fd167343",
"label": "sub category 1.2.1",
"children": []
},
{
"id": "f82b0f63-3f39-486c-9157-5c7683b8e3b2",
"label": "sub category 1.2.2",
"children": []
}
]
}
]
}
const childObj = [childobj]
const updateData=(obj)=> {
if(existingId.includes(obj.id)) obj['checked'] = true; else obj['checked'] = false
}
const traverse=(childObj)=> {
for(const obj of childObj) {
updateData(obj);
if(obj.children.length > 0) traverse(obj.children);
}
}
traverse(childObj);
Here you can ty this logic :
let desiredOutputJsonObject = {
id: "bfa3fdf8-4672-404e-baf5-0f9098a5705b",
label: "main category 1",
checked: false,
children: [
{
id: "12e544bc-91b1-4e5d-bdbc-2163a5618305",
label: "sub category 1.1",
checked: true,
children: [],
},
{
id: "3f5e5cc7-f8b2-4d75-89e1-841c66d863e6",
label: "sub category 1.2",
checked: false,
children: [
{
id: "903a727f-d94d-44ff-b2f6-a985fd167343",
label: "sub category 1.2.1",
checked: false,
children: [],
},
{
id: "fb344480-8588-4ce3-9662-f8e89069e4b4",
label: "sub category 1.2.2",
checked: true,
children: [
{
id: "fb344480-8588-4ce3-9662-f8e89069e4b9",
label: "sub category 1.2.2",
checked: false,
children: [],
},
],
},
],
},
],
};
let referenceSelectedCategories = [
{
categoryId: "12e544bc-91b1-4e5d-bdbc-2163a5618305",
productId: "efed1c38-391b-4b5a-a9f1-91f3faec5f44",
Id: "f82b0f63-3f39-486c-9157-5c7683b8e3b2",
},
{
categoryId: "fb344480-8588-4ce3-9662-f8e89069e4b4",
productId: "efed1c38-391b-4b5a-a9f1-91f3faec5f44",
Id: "b2e8681b-eec4-404d-8f87-c6314db42e30",
},
{
categoryId:"fb344480-8588-4ce3-9662-f8e89069e4b9",
productId: "efed1c38-391b-4b5a-a9f1-91f3faec5f44",
Id: "b2e8681b-eec4-404d-8f87-c6314db42e30",
},
];
let stack = [desiredOutputJsonObject];
while (stack.length) {
let desiredOutput = stack.pop();
if (desiredOutput.children) {
desiredOutput.children.forEach((node) => {
//get node whose id == category id
let result = referenceSelectedCategories.find(
(obj) => obj.categoryId === node.id
);
// while traversing if we get referenceSelectedCategories.categoryId ==desiredOutputJsonObject.id
if (result) {
node.checked = true;
}
// for traverse purpose
if (node.children.length) {
stack.push(node);
}
});
}
}
console.log(desiredOutputJsonObject);

Recursively Find and Add Them as an Array

I have this kind of table (or data structure)
There is parentIdeaId that refers to the id in ideas table itself.
Here's my unstructured data (please bear in mind this is the existing data in the database, not data that is already as it is so I have to query this first under some condition)
[{
"id": "1",
"title": "Title 1",
"parentIdeaId": null
},{
"id": "2",
"title": "Title 2",
"parentIdeaId": 1
},{
"id": "3",
"title": "Title 3",
"parentIdeaId": 2
},{
"id": "4",
"title": "Title 4",
"parentIdeaId": null
}]
I also made a function to find the data (I'm using Prisma in my real code)
function find({ id }) {
return prisma.idea.findUnique({
where: {
id
}
});
}
And a function to find the children
function responseIdeas({ parentIdeaId }) {
return prisma.idea.findMany({
where: {
parentIdeaId
}
});
}
I want the data to be filtered only linked data (by their parentIdeaId) so if I query the id "1" the result would be
[{
"id": "1",
"title": "Title 1",
"parentIdeaId": null
},{
"id": "2",
"title": "Title 2",
"parentIdeaId": 1
}{
"id": "3",
"title": "Title 3",
"parentIdeaId": 2
}]
The id: "4" isn't inserted because it's not related by its parent
Here's what I made:
const data = [
{
id: "1",
title: "Title 1",
parentIdeaId: null
},
{
id: "2",
title: "Title 2",
parentIdeaId: 1
},
{
id: "3",
title: "Title 3",
parentIdeaId: 2
},
{
id: "4",
title: "Title 4",
parentIdeaId: null
}
];
function find({ id }) {
return data.find(e => e.id === id);
}
function responseIdeas({ parentIdeaId }) {
return data.filter(e => e.parentIdeaId == parentIdeaId);
}
async function detail({ id }) {
const findChildren = async ({ id }) => {
const idea = await find({ id });
const responses = await responseIdeas({ parentIdeaId: id });
if (responses.length !== 0) {
const resolveResponses = await Promise.all(
responses.map(async ({ id }) => findChildren({ id }))
);
return [idea, ...resolveResponses];
}
return { ...idea };
};
return findChildren({ id });
}
async function run() {
const result = await detail({ id: "1" });
console.dir(result, { depth: null });
}
run();
But it ended up being like this
[
{
"id": "1",
"title": "Title 1",
"parentIdeaId": null
},
[
{
"id": "2",
"title": "Title 2",
"parentIdeaId": 1
},
{
"id": "3",
"title": "Title 3",
"parentIdeaId": 2
}
]
]
Where did I mess up? Thanks
findChildren potentially returns an array of arrays due to the fact that your returning Promise.all() -> which is a array of promises and some of those promises can be arrays.
So you can use concat to merge the result into the main array e.g like this https://codesandbox.io/s/quizzical-sun-c4khx?file=/src/index.js

add a new JSON property using existing property value

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);

Need help formatting array in JavaScript

I have a JavaScript array with the following format:
[
{
"header": true,
"id": "0",
"name": "dairy",
},
{
"category": "dairy",
"header": false,
"id": "-LSlje6ESGALGpckMhb7",
"name": "milk",
},
{
"category": "dairy",
"header": false,
"id": "-LSm9EpFg5DhW036aUle",
"name": "cheese",
},
{
"header": true,
"id": "3",
"name": "dessert",
},
{
"category": "dessert",
"header": false,
"id": "-LSm9MLZkrnvtPySw5U6",
"name": "cake",
},
{
"category": "dessert",
"header": false,
"id": "-LSmAQ0rdDLrpz0TSPuD",
"name": "pie",
},
{
"header": true,
"id": "6",
"name": "fruit",
},
{
"category": "fruit",
"header": false,
"id": "-LSlazVIGAKLakxAIa8G",
"name": "apple",
},
{
"category": "fruit",
"header": false,
"id": "-LSlb5GH6xZz-DpNVS22",
"name": "pear",
},
{
"category": "fruit",
"header": false,
"id": "-LSwWJldY1nxQrotyv-V",
"name": "strawberry",
},
{
"header": true,
"id": "10",
"name": "meat",
},
{
"category": "meat",
"header": false,
"id": "-LSljXQzfXthJbOA54Ah",
"name": "fish",
},
{
"category": "meat",
"header": false,
"id": "-LSmA2-R9pOY8abAUyST",
"name": "steak",
},
{
"category": "meat",
"header": false,
"id": "-LSmAJ4J4gIfVQ8sgPDa",
"name": "pork",
},
]
What I am trying to do, is map through this array, and transform it to the following format:
[
{
title: nameOfFirstHeader,
data: items.slice(indexOfFirstHeader, indexOfSecondHeader),
},
{
title: nameOfSecondHeader,
data: items.slice(indexOfSecondHeader, indexOfThirdHeader),
},
{
title: nameOfThirdHeader,
data: items.slice(indexOfThirdHeader, indexOfFourthHeader),
},...and so on
]
So basically there will be an object section for each 'header' that is found in the original array. Each object section data property will contain the items found between the first header and the second header, and so on, until there are no more headers. I really can't wrap my head around how I can do this. Here is a reference to the the module I am using: https://github.com/saleel/react-native-super-grid#sectiongrid-example
Thanks!
I think this may be what you're trying to accomplish...
var grouped = items.reduce((acc,obj)=>{
let {header, name} = obj;
if (header) return [...acc, { title:name, data:[] }] // either first matching header or new match. Add fresh 'header' object
if (!acc.length) return acc; //not header and none have passed. Do nothing
let allButLast = acc.slice(0, acc.length-1),
lastElem = acc[acc.length-1]; // not a header, but there is an existing match. Add it to last match's data array
return [
...allButLast,
{
...lastElem,
data:[...lastElem.data, obj]
}
]
},[])
but it seems unreliable to trust the order of an array for this purpose. It would probably be more reliable to match by isHeader.name === notHeader.category to be less presumptive about the order of data you're iterating over. Like this...
var grouped = items.reduce((acc,obj)=>{
let {header, name, category} = obj;
if (header) return [...acc, { title:name, data:[] }];
if (!acc.length) return acc;
return acc.map((elem)=>{
if (elem.title !== category) return elem;
return {
...elem,
data: [ ...elem.data, obj]
};
})
},[])
I think you can probably do something like
const data = [];
let activeIndexForData = -1;
for(let i = 0; i < dataToSort.length -1; i++) {
if(dataToSort[i].header) {
activeIndexForData++;
}
if(data.length < activeIndexForData - 1) {
data.push({ title: dataToSort[i].name, data# []})
}
else {
data[activeIndexForData].data.push({ title: dataToSort[i].name, data: [])
}
}

Filtering JSON with underscore

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

Categories