reactJS adding a object array to and object within an object array - javascript

I got a response from a REST call, which returns and array with objects
response.data.steps
For example it looks like this
Now I need to add to each Child of this array an new Object Array.
What could be a smart solution for this problem?
Thanks.

In order to add a new array property to each item, you can simply do:
const steps = response.data.steps.map(step => ({
...step,
newObjectArray: [],
}))

you can usee Array.prototype.map() to do so
let result = response.data.steps.map(element => {
let ret = [element];
return ret;
});
let arr = [{a:1}, {a:2}, {a:3}];
arr = arr.map(element => {
let ret = [element];
return ret;
});
console.log(arr);

Related

while pushing the data in to arrays, not added in order

enter image description here
i need to push the data one after another, but here i am getting to add in disorder like last added array in to first.
for (var key in data[tabName + scoreBreakDown]) {
var values = data[tabName + scoreBreakDown][key];
var staticData = values[0];
var obj = [];
obj.push(staticData.CompanyName);
obj.push(staticData.Country_ORIG);
for (var value in values) {
if (addHeader) {
headersArray.push(values[value].AspectName);
weightArray.push(values[value].ScoreWeight);
}
obj.push(values[value].SPESGScore_ORIG);
}
addHeader = false;
dataArray.push(obj);
}
You can use array.map to map through an array and transform it into a new array in order.
In this example, we are just multiplying each value by 3, but the transformation is arbitrary.
let loop = (arr) => {
return arr.map(item => {
return item*3
})
}
console.log(loop([1,2,3,4,5]))
If you want to loop through an object in order this way, you can use Object.keys() this will return an array of the keys in the object.
let loop = (obj) => {
return Object.keys(obj).map(item => {
return `${item}: ${obj[item]}`
})
}
let obj = {
first_name:"John",
last_name:"Doe",
age:23
}
console.log(loop(obj))
So instead of using a for loop and an if statement to check a condition and push the data to the array after each iteration, you can use something Array.filter() to remove entries you don't want to push, and return them in order.
data = [
{header:true, value:"item1"},
{header:false, value:"item2"},
{header:true, value:"item3"},
]
let array = data.filter(item => {return item.header}).map(item => {
return item.value
})
console.log(array)

Java script filter on array of objects and push result's one element to another array

I have a array called data inside that array I have objects.
An object structure is like this
{
id:1,
especial_id:34,
restaurant_item:{id:1,restaurant:{res_name:'KFC'}}
}
I want to pass a res_name eg:- KFC
I want an output as a array which consists all the especial_ids
like this
myarr = [12,23,23]
I could do something like this for that. But I want to know what is more elegant way to do this.
const data = [
{id:1,especial_id:6,restaurant_items:{id:5,res_name:'McDonalds'}},
{id:1,especial_id:8,restaurant_items:{id:5,res_name:'Kfc'}},
{id:1,especial_id:6,restaurant_items:{id:5,res_name:'Sunmeal'}},
{id:1,especial_id:6,restaurant_items:{id:5,res_name:'Kfc'}},
];
let temp = data.filter(element => element.restaurant_items.res_name == 'kfc')
let myArr = [];
temp.forEach(element=> myArr.push(element.especial_id));
console.log(myArr)//[8,6]
You can try this. It uses "Array.filter" and "Array.map"
var data = [
{id:1,especial_id:6,restaurant_items:{id:5,res_name:'McDonalds'}},
{id:1,especial_id:8,restaurant_items:{id:5,res_name:'Kfc'}},
{id:1,especial_id:6,restaurant_items:{id:5,res_name:'Sunmeal'}},
{id:1,especial_id:6,restaurant_items:{id:5,res_name:'Kfc'}},
];
function getEspecialIdsByName(name) {
return data.filter(d => d.restaurant_items.res_name.toLowerCase() == name.toLowerCase())
.map(d => d.especial_id)
}
console.log(getEspecialIdsByName('Kfc'))
console.log(getEspecialIdsByName('Sunmeal'))
You can reduce to push elements which pass the test to the accumulator array in a single iteration over the input:
const data = [
{id:1,especial_id:6,restaurant_items:{id:5,res_name:'McDonalds'}},
{id:1,especial_id:8,restaurant_items:{id:5,res_name:'Kfc'}},
{id:1,especial_id:6,restaurant_items:{id:5,res_name:'Sunmeal'}},
{id:1,especial_id:6,restaurant_items:{id:5,res_name:'Kfc'}},
];
console.log(
data.reduce((a, { especial_id, restaurant_items: { res_name }}) => {
if (res_name === 'Kfc') a.push(especial_id)
return a;
}, [])
);
Use Array.reduce
const data = [{id:1,especial_id:6,restaurant_items:{id:5,res_name:'McDonalds'}},{id:1,especial_id:8,restaurant_items:{id:5,res_name:'Kfc'}},{id:1,especial_id:6,restaurant_items:{id:5,res_name:'Sunmeal'}},{id:1,especial_id:6,restaurant_items:{id:5,res_name:'Kfc'}}];
let result = data.reduce((a,c) => {
if(c.restaurant_items.res_name === 'Kfc') a.push(c.especial_id);
return a;
},[]);
console.log(result);

ReactJS : RestAPI JSON response : How to Parse

As a ReactJS newbie, I tried to parse RestfulAPI JSON reponse, But, I couldn't retrieve all elements. While trying to access text.subjects.code and text.subjects.description, it returns null. However, I could successfully access text.id and text.name.
JSON response is given below.
[
{
"id":95822,
"name":"Alex",
"subjects":[
{
"code": "101",
"description": "Course 101"
}
]
}
]
Kindly advise.
You can do iteration in many ways and few ways which I always prefer using .forEach and .map
If you need new array then go with .map. Because map returns a new array
const dataArray = text.subjects.map(subject => {
let obj = {};
obj.code = subject.code;
obj.description = subject.description;
return obj;
});
//dataArray will contain all the objects
There is also a Different way of doing map
const dataArray = text.subjects.map(subject => (
let obj = {};
obj.code = subject.code;
obj.description = subject.description;
return obj;
);
Or if you want to just iterate the data then use .forEach. forEach doesn’t return an array
let array = [];
text.subjects.forEach(subject => (
let obj = {};
obj.code = subject.code;
obj.description = subject.description;
array.push(obj);
));
if You check subjects is an array and you are not getting value from it, try
text.subjects[0].code
Because subjects is an array and you should map subject like the following:
text.subjects.map((subject) => {
console.log(subject.code, subject.description);
})
or directly get the index that you to want like the following:
text.subjects[0].code

Why does a js map on an array modify the original array?

I'm quite confused by the behavior of map().
I have an array of objects like this:
const products = [{
...,
'productType' = 'premium',
...
}, ...]
And I'm passing this array to a function that should return the same array but with all product made free:
[{
...,
'productType' = 'free',
...
}, ...]
The function is:
const freeProduct = function(products){
return products.map(x => x.productType = "free")
}
Which returns the following array:
["free", "free", ...]
So I rewrote my function to be:
const freeProduct = function(products){
return products.map(x => {x.productType = "free"; return x})
}
Which returns the array as intended.
BUT ! And that's the moment where I loose my mind, in both cases my original products array is modified.
Documentation around map() says that it shouldn't ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map ).
I even tried to create a clone of my array turning my function into this:
const freeProduct = function(products){
p = products.splice()
return p.map(x => {x.productType = "free"; return x})
}
But I still get the same result (which starts to drive me crazy).
I would be very thankful to anyone who can explain me what I'm doing wrong!
Thank you.
You're not modifying your original array. You're modifying the objects in the array. If you want to avoid mutating the objects in your array, you can use Object.assign to create a new object with the original's properties plus any changes you need:
const freeProduct = function(products) {
return products.map(x => {
return Object.assign({}, x, {
productType: "free"
});
});
};
2018 Edit:
In most browsers you can now use the object spread syntax instead of Object.assign to accomplish this:
const freeProduct = function(products) {
return products.map(x => {
return {
...x,
productType: "free"
};
});
};
To elaborate on SimpleJ's answer - if you were to === the two arrays, you would find that they would not be equal (not same address in memory) confirming that the mapped array is in fact a new array. The issue is that you're returning a new array, that is full of references to the SAME objects in the original array (it's not returning new object literals, it's returning references to the same object). So you need to be creating new objects that are copies of the old objects - ie, w/ the Object.assign example given by SimpleJ.
Unfortunately, whether the spread operator nor the object assign operator does a deep copy.... You need to use a lodash like function to get areal copy not just a reference copy.
const util = require('util');
const print = (...val) => {
console.log(util.inspect(val, false, null, false /* enable colors */));
};
const _ = require('lodash');
const obj1 = {foo:{bar:[{foo:3}]}};
const obj2 = {foo:{bar:[{foo:3}]}};
const array = [obj1, obj2];
const objAssignCopy = x => { return Object.assign({}, x, {})};
const spreadCopy = x => { return {...x}};
const _Copy = x => _.cloneDeep(x);
const map1 = array.map(objAssignCopy);
const map2 = array.map(spreadCopy);
const map3 = array.map(_Copy);
print('map1', map1);
print('map2', map2);
print('map3', map3);
obj2.foo.bar[0].foo = "foobar";
print('map1 after manipulation of obj2', map1); // value changed
print('map2 after manipulation of obj2', map2); // value changed
print('map3 after manipulation of obj2', map3); // value hasn't changed!
Array Iterator Array.map() creates the new array with the same number of elements or does not change the original array. There might be the problem with referencing if there is object inside the array as it copies the same reference, so, when you are making any changes on the property of the object it will change the original value of the element which holds the same reference.
The solution would be to copy the object, well, array.Splice() and [...array](spread Operator) would not help in this case, you can use JavaScript Utility library like Loadash or just use below mention code:
const newList = JSON.parse(JSON.stringify(orinalArr))
Array Destructuring assignment can be used to clone the object.
const freeProduct = function(products){
p = products.splice()
return p.map(({...x}) => {x.productType = "free"; return x})
}
This method will not modify the original object.

Transformation array to nested object

I try to convert some data into a javascript object. The data looks like this:
data = [["a","a","a","value1"],
["a","a","b","value2"],
["a","b","value3"],
["a","c","a","value4"]]
What I want to get is:
a = {
"a":{
"a":"value1",
"b":"value2"
},
"b":"value3",
"c":{
"a":"value4"
}
}
Since the amount of nested attributes varies I do not know how to do this transformation.
This should be the function you're looking for:
function addItemToObject(dict, path){
if (path.length == 2){
dict[path[0]] = path[1];
} else {
key = path.shift()
if (! dict[key]) {
dict[key] = {};
}
addItemToObject(dict[key], path);
}
return dict;
}
var result = data.reduce(addItemToObject,{});
The function addItemToObject is a recursive function which creates the depth and inserts the value.
This is applied to everything in data using reduce;
Here's a solution using Ramda.js
const data = [
["a","a","a","value1"],
["a","a","b","value2"],
["a","b","value3"],
["a","c","a","value4"]
]
const transformData =
R.pipe(
R.map(R.juxt([R.init, R.last])),
R.reduce(
(obj, [path, value]) =>
R.assocPath(path, value, obj),
{},
),
)
console.log(transformData(data))
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>
I don't get your desired solution as there are 4 blocks of data but only 3 properties in the final object.
However, this is how you can iterate through an array and its child arrays:
var data = [["a","a","a","value1"],
["a","a","b","value2"],
["a","b","value3"],
["a","c","a","value4"]];
//Store your results in here
var result = {};
//Iterate each block of data in the initial array
data.forEach(function(block){
//block will refer to an array
//repeat with the child array
block.forEach(function(item){
//item will point to an actual item in the child array
});
});
forEach() will call a provided function on each item within an array.

Categories

Resources