how to get a field from nested JSON in Javascript? - javascript

I want to take a field from nested JSON object as a string which is used as parameter.
I'm using a github project https://github.com/bencripps/react-redux-grid.
this react component is used for tree-grid.
I have a data and I want to map it as a tree-grid view.
My nested JSON object is below. It comes from an API. I want to take "2020.total" as a parameter (line 4)
"id": 1,
"parentId": -1,
"Name": "Category 1",
"2020": {total:120, tax:12},
"children": [{
"id": 11,
"parentId": 1,
"Name": "Category 11",
"2020": {total:23, tax:2},
}]
when i finally get this parameter i use it as a variable in below code (line 16)
const complexData = {
showTreeRootNode: false,
data:datafromAPI,
gridType: 'tree',
dragAndDrop: true,
columns: [
{
name: 'Name',
className: 'additional-class',
dataIndex: 'Name',
sortable: false,
expandable: true
},
{
name: 'Total Payment',
dataIndex: 2020.total,
sortable: false,
className: 'additional-class'
}],
};
"Name" attribute is working fine but "Total Payment" is not working.
i tried those syntax;
'2020.total'
'[2020].total'
'[2020][total]'
I know this is a little bit syntax question but i don't know how to search for it.
thanks for all answer.

let a = {
"id": 1,
"parentId": -1,
"Name": "Category 1",
"2020": {total:120, tax:12},
"children": [{
"id": 11,
"parentId": 1,
"Name": "Category 11",
"2020": {total:23, tax:2},
}]
}
Try a[2020].total

You can access it like this:
let a = {
"2020": {total:120, tax:12},
}
a[2020].total
a["2020"].total

Related

react js :fetch data from inner array and load it to state

i have a api with peoples i am tring to dispaly names of people
"peoples": [
{
"id": 2,
"mainModule": "bonding",
"description": "some random description 2",
"persons": [
{
"id": 3,
"name": "hari",
"completed": false
},
{
"id": 4,
"name": "meenu",
"completed": false
}
]
"id": 1,
"mainModule": "bonding2",
"description": "some random description 2",
"persons": [
{
"id": 3,
"name": "jisa",
"completed": false
},
{
"id": 4,
"name": "stepy",
"completed": false
}
]
},
]
This is my data in api
I am using axios to set a state called items
axios
.get(
"url",
config
)
.then((res) => {
console.log(res.data.peoples)//this works
console.log(res.data.peoples.persons);//here i am getting error
this.setState({ items: res.data.peoples.persons}); error
}
I am trying to pass persons so I can map person names in JSX
i have changed the code pls help
Welcome to StackOverflow! As you can see in your first snippet you have an array inside peoples so the correct way to access it would be:
res.data.peoples[0].persons
Hope this solves your problem. You can read more about it in MDN docs
edit:
If you would like to iterate over persons you can do this:
res.data.peoples.map(person => (
<div key={person.id}>{person.name}</div>
));
Remember you must pass a unique key prop to the component so React can create and mantain the list correctly. More info about it in the Docs.
res.data.peoples is an array so you should iterate over it. It doesn't have persons property, it has [0], [1] etc. Try to log res.data.peoples[0].persons
From the sample data you showed, peoples is an array. So to access persons, you should be able to access it using the following, for example if you want to access the first element of the array:
res.data.peoples[0].persons
Otherwise, if you want to access it as res.data.peoples.persons then you have to change your API output such that it is like so :
"peoples": {
"id": 2,
"mainModule": "bonding",
"description": "some random description 2",
"persons": [
{
"id": 3,
"name": "hari",
"completed": false
},
{
"id": 4,
"name": "meenu",
"completed": false
}
]
}

How to find all specific keys in multiple level NESTED JSON in one loop, and for every of them change value

how to get the index number for every object inside the array.
I have JSON with multiple nested arrays of objects, and I need to set to the POSITION key index number.
I get this JSON dynamically, and I need to loop thru the JSON and on every POSITION key need to set indexOF() number to get object position inside array.
My problem is, how to find all keys with name POSITION and set indexOf() number for a value?
I know, and I try to get it in loop for every nested array, but is there any BETTER way? Faster way?
Here is example with nested for loops
Thnx
Here is JSON
{
"id": 175,
"name": "dag",
"title": "dfgd",
"page": [{
"id": 551,
"name": "page1",
"title": "Page 1",
"position": 0, ---> here I need set index number for obj in this page array
"questions": [{
"id": 70,
"name": "text1",
"text": "Questitexton 1",
"position": 0, ---> here I need set index number for obj in this questions array
"data": [{
"id": 56,
"name": "data",
"position": 0, ---> here I need set index number for obj in this data array
"text": "Control 3"
}]
}, {
"id": 69,
"name": "data3",
"text": "data 3",
"position": 1, ---> here I need set index number for obj in this array
"data": [{
"id": 55,
"name": "data2",
"position": 0, ---> here I need set index number for obj in this data array
"text": "Control 3"
}]
}]
}, {
"id": 552,
"name": "page2",
"title": "Page 2",
"position": 1, ---> here I need set index number for obj in this page array
"questions": [{
"id": 73,
"name": "text1",
"text": "Questitexton 1",
"position": 0, ---> here I need set index number for obj in this questions array
"data": [{
"id": 75,
"name": "data",
"position": 0, ---> here I need set index number for obj in this data array
"text": "Control 3"
}]
}, {
"id": 45,
"name": "data3",
"text": "data 3",
"position": 1, ---> here I need set index number for obj in this questions array
"data": [{
"id": 798,
"name": "data2",
"position": 0, ---> here I need set index number for obj in this data array
"text": "Control 3"
}]
}]
}]
}
My current attempt
const animals = [{
id: 175,
name: "dag",
title: "dfgd",
page: [{
id: 551,
name: "page1",
title: "Page 1",
position: null,
questions: [{
id: 70,
name: "text1",
text: "Questitexton 1",
position: null,
data: [{
id: 56,
name: "data",
position: null,
text: "Control 3"
}]
},
{
id: 69,
name: "data3",
text: "data 3",
position: null,
data: [{
id: 55,
name: "data2",
position: null,
text: "Control 3"
}]
}
]
},
{
id: 552,
name: "page2",
title: "Page 2",
position: null,
questions: [{
id: 73,
name: "text2",
text: "Questitexton 1",
position: null,
data: [{
id: 75,
name: "data",
position: null,
text: "Control 3"
}]
},
{
id: 45,
name: "data5",
text: "data 3",
position: null,
data: [{
id: 798,
name: "data2",
position: null,
text: "Control 3"
}]
}
]
}
]
}];
for (let data of animals) {
for (let data1 of data.page) {
data1.position = data.page.indexOf(data1);
for (let data2 of data1.questions) {
data2.position = data1.questions.indexOf(data2);
for (let data3 of data2.data) {
data3.position = data2.data.indexOf(data3);
}
}
}
}
console.log(animals);
You could clone the object and add the index if position is found.
const addIndex = (o, i) => Object.fromEntries(Object.entries(o).map(([k, v]) => [
k,
k === 'position'
? i
: Array.isArray(v)
? v.map(addIndex)
: v
]));
var animals = [{ id: 175, name: "dag", title: "dfgd", page: [{ id: 551, name: "page1", title: "Page 1", position: null, questions: [{ id: 70, name: "text1", text: "Questitexton 1", position: null, data: [{ id: 56, name: "data", position: null, text: "Control 3" }] }, { id: 69, name: "data3", text: "data 3", position: null, data: [{ id: 55, name: "data2", position: null, text: "Control 3" }] }] }, { id: 552, name: "page2", title: "Page 2", position: null, questions: [{ id: 73, name: "text2", text: "Questitexton 1", position: null, data: [{ id: 75, name: "data", position: null, text: "Control 3" }] }, { id: 45, name: "data5", text: "data 3", position: null, data: [{ id: 798, name: "data2", position: null, text: "Control 3" }] }] }] }],
result = animals.map(addIndex);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You can't really do it in a one-liner but if you create a re-usable function to set a position on an array, then you can do it quite quickly.
My code creates a copy of your original array, but that shouldn't be such a problem per say, I am sure you could work around it if you like
function getPositionedObject( objToCopy, position = 0 ) {
// take all the keys on the object
return Object.keys( objToCopy ).reduce( (agg, key) => {
// get the value once
const value = objToCopy[key];
if (Array.isArray( value ) ) {
// if it's an array, iterate all the items and re-use this function
agg[key] = value.map( getPositionedObject );
} else {
// if it's not keep the value as is
agg[key] = value;
}
return agg;
}, { position }); // start with the position that was passed as a parameter
}
With your dataset (I removed the initial positions from the code you have given, it kinda looks like the following)
const dataset = {
"id": 175,
"name": "dag",
"title": "dfgd",
"page": [{
"id": 551,
"name": "page1",
"title": "Page 1",
"questions": [{
"id": 70,
"name": "text1",
"text": "Questitexton 1",
"data": [{
"id": 56,
"name": "data",
"text": "Control 3"
}]
}, {
"id": 69,
"name": "data3",
"text": "data 3",
"data": [{
"id": 55,
"name": "data2",
"text": "Control 3"
}]
}]
}, {
"id": 552,
"name": "page2",
"title": "Page 2",
"questions": [{
"id": 73,
"name": "text1",
"text": "Questitexton 1",
"data": [{
"id": 75,
"name": "data",
"text": "Control 3"
}]
}, {
"id": 45,
"name": "data3",
"text": "data 3",
"data": [{
"id": 798,
"name": "data2",
"text": "Control 3"
}]
}]
}]
};
function getPositionedObject( objToCopy, position = 0 ) {
return Object.keys( objToCopy ).reduce( (agg, key) => {
const value = objToCopy[key];
if (Array.isArray( value ) ) {
agg[key] = value.map( getPositionedObject );
} else {
agg[key] = value;
}
return agg;
}, { position });
}
console.log( getPositionedObject( dataset ) );

React / Redux - how to render/update deeply nested sate

I'll get from the API a deeply nested state - e.g.:
[{
"id": 1,
"text": "test",
"children": [{
"id": 1,
"text": "test",
"children": [{
"id": 1,
"text": "test",
"children": [{
"id": 1,
"text": "test",
"children": []
}]
}]
}]
}]
(Please ignore duplicate ids etc)
Now here are the requirements:
I need to properly render this
e.g.
<div>
text
<div>
text
</div>
</div>
I need to be able to update the nested state within redux store
This list can be huge - like at least 3k items (which theoretically works fine)
What I tried:
Having everything unnested:
Rendering is very complicated (with parentId)
Maintaining the structure is difficult (need to flatten and unflatten it) -> this costs a lot of performance
Having everything nested:
Updating the store is impossible without "cheating" in react -> manipulating the state directly
What can be a solution to this? What should be the architecture
Something like immutability-helper will probably be of use to you here.
const state = [{
"id": 1,
"text": "test",
"children": [{
"id": 1,
"text": "test",
"children": [{
"id": 1,
"text": "test",
"children": [{
"id": 1,
"text": "test",
"children": []
}]
}]
}]
}];
const newState = update(state, {
0: {
children: {
0: {
children {
0 : {
children: {
0: {
"id": { $set: 2}
}
}
}
}
}
}
};
return newState;
[{
"id": 1,
"text": "test",
"children": [{
"id": 1,
"text": "test",
"children": [{
"id": 1,
"text": "test",
"children": [{
"id": 2,
"text": "test",
"children": []
}]
}]
}]
}];
The 0s here could be replaced with some indexes in your payload; I just used 0 here as the example arrays all have only 1 element in them. This is quite deeply nested though so as the comments pointed out, any flattening you can do will make the updates easier.

Check for Parent Child node in JSON using angular JS

I am looking for JSON parsing reference, from where I can jump to question and check for Child question based on Yes section. I didn't find anything related to check for child node check in JSON. Angular is my base framework.
some use cases :
on load show Root question,
On selection show next questions which is child of root then go one
jump to number of questions from tree.
treeObj={
"Root_Element": {
"id": "myTree",
"dt": {
"choice": {
"id": '0',
"title": "Which color",
"description": "Choose color ?",
"choice": [
{
"id": 1,
"title": "Yellow",
"description": "Yellow ? ,
"choice": [
{
"id": 5,
"title": "Dark Yellow",
"description": "Dark Yellow ?
},
{
"id": 4,
"title": "Light Yellow",
"description": "Light Yellow ?
}
]
},
{
"id": 2,
"title": "Red",
"description": "Red ?"
},
{
"id": 3,
"title": "Green",
"description": "Green ?
}
]
}
}
}
}
If the number of levels in the JSON object is fixed and if it does not grow dynamically, you can use the ES6 destructuring to read the data from the nested JSON. Below is an example
var metadata = {
title: "Scratchpad",
translations: [
{
locale: "de",
localization_tags: [ ],
last_edit: "2014-04-14T08:43:37",
url: "/de/docs/Tools/Scratchpad",
title: "JavaScript-Umgebung"
}
],
url: "/en-US/docs/Tools/Scratchpad"
};
var { title: englishTitle, translations: [{ title: localeTitle }] } = metadata;
console.log(englishTitle); // "Scratchpad"
console.log(localeTitle); // "JavaScript-Umgebung"

AngularJS JSON scope

I'm trying to make my Angular controller more generic in the way it handles JSON array of objects.
Currently I have the following defined:
$scope.Data = [];
and I pull across the data in my template like:
ng-repeat="item in Data.category[3].values
My JSON looks like:
"category": [{
"name": "cat1",
"behaviour": "normal",
"selected": 0,
"values": [{
"label": "define",
"count": 6
}]
}, {
"name": "cat2",
"behaviour": "normal",
"selected": 0,
"values": [{
"label": "type",
"count": 6
}]
}, {
"name": "Company",
"behaviour": "multi-select",
"selected": 0,
"values": [{
"label": "VW",
"count": 4
}, {
"label": "Renault",
"count": 1
}, {
"label": "Fiat",
"count": 1
}]
}, {
"name": "Make",
"behaviour": "multi-select",
"selected": 0,
"values": [{
"label": "Gold",
"count": 3
}]
}, {
"name": "Color",
"behaviour": "normal",
"selected": 0,
"values": [{
"label": "White",
"count": 3
}, {
"label": "Blue",
"count": 2
}, {
"label": "Green",
"count": 1
}]
}]
What I'm trying to do is rather than access a specific index with:
Data.category[3].values
I'd like to loop through category and grab a list of index items so I can use like:
Data.category[Color].values
where Color is found in the list, and I can bring back the values for that specific element, is that possible?
You would use filter instead, you can also pass Color value dynamically through scope.
Markup
ng-repeat="item in (Data.category| {name: 'Color'}: true)[0].values
Update
You could pass Color variable dynamically through another scope variable, like $scope.color = 'Color' so the ng-repeat will become
Html
ng-repeat="item in (Data.category| {name: color}: true)[0].values
I am not sure this is what you want but if you need to display value in function of color attribute you could do this in your controller:
$scope.dataToDisplay = [];
for(var i = 0; i < $scope.Data.length ; i++){
{
if($scope.Data.color == 'yourcolor') {
$scope.dataToDisplay.push($scope.Data[i].values)
}
}
And in your HTML you just display dataToDisplay

Categories

Resources