Parse json object and read values - javascript

I want to be able to parse this json tree and get the value of the attribute checked for every element :
{
"children": [
{
"children": [
{
"children": [],
"id": 49,
"name": "nice",
"checked": true,
"level": 3,
"path": "0_1_0_0",
"lineLength": 180
}
],
"id": 48,
"name": "amira",
"checked": false,
"level": 2,
"path": "0_1_0"
}
],
"id": 47,
"name": "mahdi",
"checked": true,
"level": 1,
"path": "0_1"
}
I'm able to read the data this way :
var data = this.flatData;
I want to be able to read the checked attribute for every child inside a for loop or a foreach and if it's true set a certain behaviour to my code do any one know how to do this and thanks in advance.

You can use a recursion; in your particular structure something like:
const func = (elem) => {
if (elem.children) elem.children.forEach((elem) => func(elem));
if (elem.checked) console.log(`act on elem with id: ${elem.id}`);
}
func(test);

Related

Object has many arrays, loop through each and change some value

I have an object that has a whole host of arrays and properties. There is a property called targetProperty which appears in various places of the object.
I have a function where if the user clicks yes, every instance of that property needs to be reassigned to a new value.
The problem is the function that I used for assigning a new value doesn't work in this senario:
reassingPropertyInObj(obj, status) {
if (typeof obj === 'object' && obj !== null) {
obj.targetProperty = status;
for (const key in obj) {
this.handleExpandCollapseClick(obj[key], status);
}
}
},
Does anyone have a solution for this? Also can't use JSON.parse() or anything like that because the properties need to stay reactive for later reassignment if needed by the user.
Below is an example of one object:
{
"id": 16,
"ref_study_id": "3412333",
"title": "SomePersonNameOne",
"capabilities_available": [
{
"id": 75,
"name": "Clinical Data",
},
{
"id": 538,
"name": "RK's Capability",
}
],
"capabilities_impacted": [],
"businessImpact": {
"id": 2,
"name": "Medium"
},
"sites_impacted": [],
"sites_available": []
},
{
"id": 6,
"ref_study_id": "123124",
"title": null,
"capabilities_available": [
{
"id": 37,
"name": "Clinical Site Experience,
},
{
"id": 41,
"name": "Experience",
}
],
"capabilities_impacted": [
{
"id": 37,
"name": "Information Exchange",
"is_study_level": false,
"businessImpact": {
"id": 2,
"name": "Medium"
}
},
{
"id": 39,
"name": "IT/Data Experience",
"is_study_level": false,
"businessImpact": {
"id": 2,
"name": "Medium"
}
},
{
"id": 34,
"name": "Mgmt & Storage",
"is_study_level": false,
"businessImpact": {
"id": 3,
"name": "Minor"
}
}
],
"businessImpact": {
"id": 2,
"name": "Medium"
},
"sites_impacted": [],
"sites_available": []
},
And the property in question is businessImpact. As you can see it appears by itself as a property and inside array (and sometimes those arrays of arrays of their own).
I setup a function like:
arrayOfProperties.forEach((property) => {
obj[property].forEach((o) => {
o.businessImpact = newVal;
});
});
But of course it doesn't go deep enough.

Accessing a specific key in JSON?

I'm trying to access the "title" section (key?) of this JSON object using NodeJS. I can return the entire object, but every time I try to access the key, undefined is returned.
[
[
{
"id": 119,
"title": "Roadhouse",
"url": "https://funsite.com/2021/03/20/funny/",
"date": "2021-03-20"
}
],
[
{
"id": 208,
"title": "New Sites",
"url": "https://coolsitestuff.com/notes/coolsite/",
"date": "2021-03-17"
}
],
[
{
"id": 13,
"title": "woah sites!!",
"url": "https://now.lettuce.com/then/2021-0000/",
"date": "2021-03-07"
}
],
[
{
"id": 120,
"title": "mynewalbumn",
"url": "https://notarealsite.com/2021/03/06/next-album/",
"date": "2021-03-06"
}
],
[
{
"id": 140,
"title": "fightingthemans",
"url": "http://fightcats.com/2021/03/06/keyfights",
"date": "2021-03-06"
}
],
[
{
"id": 14,
"title": "biggest lettuce youll ever see",
"url": "https://morelettuce.com/then/biggestlettuceleaf/",
"date": "2021-02-28"
}
]
]
NodeJS
const fs = require('fs')
fs.readFile('./data/links.json', 'utf8', (err, fsToString) => {
let data = JSON.parse(fsToString);
console.log(data.map(link => link[link.url]))
})
I've tried for loops and indexing that way but I haven't been able to get anything out of it.
You have 2 arrays, either loop over both of them or access it using index
let data =[
[
{
"id": 119,
"title": "Roadhouse",
"url": "https://funsite.com/2021/03/20/funny/",
"date": "2021-03-20"
}
],
[
{
"id": 208,
"title": "New Sites",
"url": "https://coolsitestuff.com/notes/coolsite/",
"date": "2021-03-17"
}
]
]
data.map(link=> console.log(link[0].url))
Your json is array of array objects, you need to access all arrays by index, you can use flatMap and map methods.
var data = [
[{
"id": 119,
"title": "Roadhouse",
"url": "https://funsite.com/2021/03/20/funny/",
"date": "2021-03-20"
}],
[{
"id": 208,
"title": "New Sites",
"url": "https://coolsitestuff.com/notes/coolsite/",
"date": "2021-03-17"
}],
[{
"id": 13,
"title": "woah sites!!",
"url": "https://now.lettuce.com/then/2021-0000/",
"date": "2021-03-07"
}],
[{
"id": 120,
"title": "mynewalbumn",
"url": "https://notarealsite.com/2021/03/06/next-album/",
"date": "2021-03-06"
}],
[{
"id": 140,
"title": "fightingthemans",
"url": "http://fightcats.com/2021/03/06/keyfights",
"date": "2021-03-06"
}],
[{
"id": 14,
"title": "biggest lettuce youll ever see",
"url": "https://morelettuce.com/then/biggestlettuceleaf/",
"date": "2021-02-28"
}]
];
console.log(data.flatMap(i=>i.map(f=>f.url)))
Your current code is trying to access an undefined object property.
Solution:
Replace the link[link.url] for link[0].url. So that the full line is
console.log(data.map(link => link[0].url))
Or if you want the titles:
console.log(data.map(link => link[0].title))
console.log(
data.flat().map(link=>link.url)
);
console.log(
data.map(item=>item[0].url)
);
From what I see your JSON file holds an array of arrays and each nested array contains one object. Therefore data.map(link => link[0].title) should return array of titles
You have an array of arrays and each one with just one position. For the code you posted you're just missing the index of each element.
If you change your code to this you'll get the array with the URL's you're looking for
fs.readFile('./example.json', 'utf8', (err, fsToString) => {
let data = JSON.parse(fsToString);
console.log(data.map(link => link[0].url))
})
Happy coding ;)!

Javascript For Each Object inside Array containing a property that is Array check If Value Matches

For each object inside this array containing userHandle array loop through that array(userHandle one) and check if one of those values matches some string I choose called uid. How to write that code in Javascript?
Array [
Object {
"avatar": null,
"hugCount": 2,
"id": 35,
"liked": false,
"name": "fhfdhdhf",
"text": "Yoho",
"timestamp": 1610471860157,
"uid": "FOgepuJqxXfkHxI8OAV2KMWodXo1",
},
Object {
"avatar": null,
"hugCount": 1,
"id": 34,
"liked": true,
"mood": 2,
"name": "fhfdhdhf",
"text": "I'm fine today.",
"timestamp": 1607943705709,
"uid": "FOgepuJqxXfkHxI8OAV2KMWodXo1",
"userHandle": Array [
"Aw8AUj1mPkON1Fd1s6LhkNETHfb2",
"LrIwIx9I1xQBJ7aeCSrinpEaDP53",
],
}]
Try this code:
var uid = "LrIwIx9I1xQBJ7aeCSrinpEaDP53";
yourArray.forEach(function(item, _){
return item['userHandle']?.indexOf(uid);
});
The '?' is to make sure your Object contains the 'userHandle' property
This is the function you need... and below you can see how to use it.
You need to pass the value you are looking for, and the array with the information.
function findInUserHandle(uidValue, array)
{
return array.reduce
(
(acum, current) =>
current.userHandle && current.userHandle.indexOf(uidValue) !== -1 || acum,
false
)
}
let array = [
{
"avatar": null,
"hugCount": 2,
"id": 35,
"liked": false,
"name": "fhfdhdhf",
"text": "Yoho",
"timestamp": 1610471860157,
"uid": "FOgepuJqxXfkHxI8OAV2KMWodXo1",
},
{
"avatar": null,
"hugCount": 1,
"id": 34,
"liked": true,
"mood": 2,
"name": "fhfdhdhf",
"text": "I'm fine today.",
"timestamp": 1607943705709,
"uid": "FOgepuJqxXfkHxI8OAV2KMWodXo1",
"userHandle":[
"Aw8AUj1mPkON1Fd1s6LhkNETHfb2",
"LrIwIx9I1xQBJ7aeCSrinpEaDP53",
],
}
]
findInUserHandle('something', array) //? false
findInUserHandle('Aw8AUj1mPkON1Fd1s6LhkNETHfb2', array) //? true
findInUserHandle('mood', array) //? false

Concatenating child array to parent

Right now I have an array of object with children that also have an array of objects.
[
{
"code": "mock-code",
"name": "mock-name",
"children": [
{
"code": "mock-child-code",
"name": "mock-child-name",
},
{
"code": "mock-child-code",
"name": "mock-child-name",
},
],
},
{
"code": "mock-code",
"name": "mock-name",
"children": [],
},
{
"code": "mock-code",
"name": "mock-name",
"children": [
{
"code": "mock-code",
"name": "mock-name",
}
],
}
]
I want to extract the children array and concat them to the parent array like below.
[
{
"code": "m1",
"name": "mock-name",
"children": [
{
"code": "mc-1",
"name": "mn-1",
},
{
"code": "mc-2",
"name": "mn-2",
},
],
},
{
"code": "m2",
"name": "mock-name",
"children": [],
},
{
"code": "mm3",
"name": "mock-name",
"children": [
{
"code": "mc-3",
"name": "mn-3",
}
],
}
{
"code": "mc-1",
"name": "mn-1",
},
{
"code": "mc-2",
"name": "mn-2",
},
{
"code": "mc-3",
"name": "mn-3",
}
]
What are someways to do this. I'm currently looping though the child array creating a new array checking if it's not empty. It all seems a bit messy. Is there a clean way to do this?
let fullList = New Array()
parentData.forEach(element => {
if (!!element.children.length) {
fullList.push(element.children);
}
});
return parentData.concat(fullList);
This isn't giving me the desired results since it's adding another array to the parent object but this is where I am at.
const newArray = originalArray.flatMap(element => [element, ...element.children])
This should do it, and as a bonus will preserve the order (parent1, parent1's children, parent2, parent2's children etc.)
Of course, this works if you have only one level of nesting. If you have greater depth level, that would be a bit more complex, probably using Array.prototype.reduce().

nested filter with lodash for parent children relationship

How to create a lodash to get the userID 10165381978 and its children userIDs for the following multi array ($scope.myVar)-
{
"children": [{
"userId": "1",
"name": "Kevin",
"type": "ROOT",
"active": true,
"children": [{
"userId": "10023872531",
"name": "Selvin",
"type": "USER",
"active": true,
"children": []
}, {
"userId": "10003200835",
"name": "adduser",
"type": "USER",
"active": true,
"children": []
}, {
"userId": "-1111111",
"name": "Merisa",
"type": "USER",
"active": true,
"children": []
}, {
"userId": "10165381976",
"name": "Kam",
"type": "PARENT",
"active": true,
"children": [{
"userId": "10165381977",
"name": "Pam",
"type": "USER",
"active": true,
"children": [{
"userId": "10165381978",
"name": "Ram",
"type": "PARENT",
"active": true,
"children": [{
"userId": "10232392492",
"name": "Sam",
"type": "USER",
"active": true,
"children": []
}]
}]
}]
}]
}]
}
So from above I want to get-
10165381978, 10232392492
I tried-
var filterUser = function(userId){
lodash.filter($scope.myVar, function(o) { return o.userId})
}
And then called filterUser(10165381978);
But the result was empty object [].
Lodash does not provide a built-in utility to achieve this. You can solve this by recursively traversing throughout your nested collections. Check the solution below, each section of the code is commented.
function getIds(collection, ids) {
// store ids in this variable
var result = [];
// determines if an id is found,
var found = false;
// makes sure that ids is always an array of id
ids = [].concat(ids);
// iterate over the collection, name the callback for recursion
// if you prefer to use lodash, then use:
// _.each(collection, function iterator(value) {...});
collection.forEach(function iterator(value) {
// Matching the list of `ids` from the iterated userId.
// If a match is found, then we set `found` to true.
var isStop = ~ids.indexOf(value.userId) && (found = true);
// did we get a match?
if(found) {
// add the matched ID and the IDs from its descendants
result.push(value.userId);
}
// itereate recursively over its descendants
// If you prefer to use lodash then use:
// _.each(value.children, iterator)
(value.children || []).forEach(iterator);
// is the currently iterated item's ID within the list of `ids`?
if(isStop) {
// set `found` to false, to prevent adding IDs that aren't matched
found = false;
}
});
// return an array of IDs
return result;
}
var data = {
"children": [{
"userId": "1",
"name": "Kevin",
"type": "ROOT",
"active": true,
"children": [{
"userId": "10023872531",
"name": "Selvin",
"type": "USER",
"active": true,
"children": []
}, {
"userId": "10003200835",
"name": "adduser",
"type": "USER",
"active": true,
"children": []
}, {
"userId": "-1111111",
"name": "Merisa",
"type": "USER",
"active": true,
"children": []
}, {
"userId": "10165381976",
"name": "Kam",
"type": "PARENT",
"active": true,
"children": [{
"userId": "10165381977",
"name": "Pam",
"type": "USER",
"active": true,
"children": [{
"userId": "10165381978",
"name": "Ram",
"type": "PARENT",
"active": true,
"children": [{
"userId": "10232392492",
"name": "Sam",
"type": "USER",
"active": true,
"children": []
}]
}]
}]
}]
}]
};
function getIds(collection, ids) {
// store ids in this variable
var result = [];
// determines if an id is found,
var found = false;
// makes sure that ids is always an array of id
ids = [].concat(ids);
// iterate over the collection, name the callback for recursion
// if you prefer to use lodash, then use:
// _.each(collection, function iterator(value) {...});
collection.forEach(function iterator(value) {
// Matching the list of `ids` from the iterated userId.
// If a match is found, then we set `found` to true.
var isStop = ~ids.indexOf(value.userId) && (found = true);
// did we get a match?
if(found) {
// add the matched ID and the IDs from its descendants
result.push(value.userId);
}
// itereate recursively over its descendants
// If you prefer to use lodash then use:
// _.each(value.children, iterator)
(value.children || []).forEach(iterator);
// is the currently iterated item's ID within the list of `ids`?
if(isStop) {
// set `found` to false, to prevent adding IDs that aren't matched
found = false;
}
});
// return an array of IDs
return result;
}
console.log('ID to find: 10165381978');
console.log(getIds(data.children, '10165381978'));
console.log('IDs to find: 10023872531, 10165381976');
console.log(getIds(data.children, [
'10023872531',
'10165381976'
]));
.as-console-wrapper {
min-height: 100%;
top: 0;
}

Categories