Array.map function isn't applying to Object value - javascript

I'm attempting to re-map an Object that comes from an API call.
The format of the response is the following:
data: {
foo: [{
id: "1",
name: "joe",
info: "whatever"
}, {
id: "2",
name: "anna",
info: "whatever"
},...],
bar: [...]
}
The code I'm using to re-map the object inside each response array is:
const DATA = response.data;
const entries = Object.entries(DATA);
for (const entry of entries) {
entry[1].map(entry => ({
id: entry["id"],
mixed_info: entry["name"] + ", " + entry["info"]
}));
}
When I console.log the data after this, it shows the same as the initial response, as if it completly ignored the map function.
What am I doing wrong? Thanks for the attention.

map returns a new array, you are ignoring the result of the call.

Assign the result of the map call:
entry[1] = entry[1].map(...);
Array.prototype.map returns a new array - it doesn't modify the original.

You have to reassign the entry:
entry[1] = entry[1].map(/*...*/);
However that will only get reflected to the array inside entries, it won't change DATA. To change that, you have to either turn the key value pairs back into an object at the end:
DATA = Object.fromEntries(entries);
Or you have to reassign the DATA properties while iterating:
DATA[ entry[0] ] = entry[1].map(/*...*/);
I'd do:
const { data } = response;
for(const [key, value] of Object.entries(data)) {
data[key] = value.map(/*...*/);
}

let result = {};
for (const entry of entries) {
result[entry[0]] = entry[1].map(entry => ({
id: entry.id,
mixed_info: `${entry["name"] }, ${ entry["info"]}`,
}));
}
'result' contains exact remapped object.

Related

How to map through an array and dynamically set key and values inside mapped array in javascript

I have an array arr with the below format
data:{
result: [Array]
}
I am mapping an array and setting key and values to form new array like this.
const userData= arr.map((user) => ({
userid : user.data.result[0].info.uid,
termStat: user.data.result[0].info['attr'].termStat
}));
This will give me the userData array as
[{
userid: 'y74',
termStat:[[Object]]
}]
How can I make this to the below format. Placing key as the value of userid.
This is the expected result
{
y74: { termStat: [[Object]]
}
You can set the key as the userid.
const arr = [{
data: {
result: [
{
info: {
uid: 12,
attr: {
termStat: 'foobar'
}
}
}
]
}
}]
const userData= arr.map(user => ({
[user.data.result[0].info.uid]: {
'termStat': user.data.result[0].info['attr'].termStat
}
}));
console.log(userData)
Array map function always returns an array. If you want to return a map from the input array Array.reduce() function will be helpful. Something like:
const arr = [{ data: { result: [{ info: { uid: 'y74', attr: { termStat: [[{}]] } } }] } }];
const userData = arr.reduce((result, user) => {
const key = user.data.result[0].info.uid;
const termStat = user.data.result[0].info['attr'].termStat;
result[key] = {termStat};
return result;
}, {});
console.log(userData);
Hope this helps :)
You can just use the userid as a variable putting it in a square brackets and assing it a value if I understand it correctly
[user.data.result[0].info.uid]: {'termStat': user.data.result[0].info['attr'].termStat}

how to convert nested array of objects to object of array

I have got array of nested array of objects .
const data = [ {group: [{label:"1"}]}, {topGroup: [{label:"2"}]} ]
I want to convert array to this format of objects and I want to get this output
let permission ={
group:["1"],
topGroup:["2"]
}
How can I do this ?
const data = [ {group: [{label:"1"}]}, {topGroup: [{label:"2"}]} ]
const converted = data.reduce((a,b) => {
const onlyKey = Object.keys(b)[0];
a[onlyKey] = b[onlyKey].map(i => i.label);
return a;
}, {})
console.log(converted)
const data = [ {group: [{label:"1"}]}, {topGroup: [{label:"2"}]} ]
let permission = {};
data.forEach(val =>{
for(prop in val){
permission[prop] = [val[prop][0]["label"]]
}
})
console.log(permission)
Give this a upvote if this is what you want.
Assuming the data is going to have labels as in that format forever, you could use something like that
const data = [{"group":[{"label":"1"}]},{"topGroup":[{"label":"12"}]}];
// The dict variable under here is the second parameter of reduce that I passed it `{}`.
// The ind variable is the data at the index of the array.
var newData = data.reduce(function(dict, ind){
// You basically get the keys and the values and put them in place
// and return the last state to the reduce function.
dict[Object.keys(ind)] = Object.values(ind)[0][0]["label"];
return dict;
}, {})
console.log(newData)
Use destructuring and Object.fromEntries.
const data = [{ group: [{ label: "1" }] }, { topGroup: [{ label: "2" }] }];
const permission = Object.fromEntries(
data.map(item => {
const [[key, [obj]]] = Object.entries(item);
return [key, Object.values(obj)];
})
);
console.log(permission);

How to convert url array query to object in Javascript

I have an URL with query params like this:
myLocalSite/?attributes%5B0%5D%5Bname%5D=customer_property_number&attributes%5B0%5D%5Bop%5D=equal&attributes%5B0%5D%5Bvalue%5D=12&attributes%5B1%5D%5Bname%5D=feedback_tags&attributes%5B1%5D%5Bop%5D=in&attributes%5B1%5D%5Bvalue%5D=test+1%2Cwww
after JSON parsing it convert into next structure
{
attributes[0][name]: "customer_property_number"
attributes[0][op]: "equal"
attributes[0][value]: "12"
attributes[1][name]: "feedback_tags"
attributes[1][op]: "in"
attributes[1][value]: "test 1,www"
}
In the end, I need an array that look like this:
attributes = [
{
name: 'customer_property_number',
op: 'equal',
value: '12',
},
{
name: 'feedback_tags',
op: 'in',
value: 'test 1, www',
},
]
Now does anyone know how I can then put these items into attributes array?
Thanks!
Here is the approach using URLSearchParams and going over each search param, parse and push to array of objects.
var sp = new URLSearchParams(
"myLocalSite/?attributes%5B0%5D%5Bname%5D=customer_property_number&attributes%5B0%5D%5Bop%5D=equal&attributes%5B0%5D%5Bvalue%5D=12&attributes%5B1%5D%5Bname%5D=feedback_tags&attributes%5B1%5D%5Bop%5D=in&attributes%5B1%5D%5Bvalue%5D=test+1%2Cwww"
);
var attributes = [];
for (entry of sp) {
const [attr, value] = entry;
const [index, key] = attr
.split("[")
.filter(x => x.includes("]"))
.map(x => x.slice(0, -1));
if (!attributes[Number(index)]) {
attributes[Number(index)] = {};
}
attributes[Number(index)][key] = value;
}
console.log(attributes);

Push objects into an array in reactjs

I'm getting a list of objects as a response like this
As you can see the objects are not in an array. I want to push these objects into an array. I tried the following way
this.setState({
countrydata: this.state.countrydata.push(datasnapshot.val()),
})
But it didn't work. What's the correct approach to push these objects into an array?
PS:
componentDidMount() {
const countryCode = this.props.match.params.countryCode;
var countryName = getName(countryCode);
var firebaseHeadingref = firebase.database().ref(countryCode);
firebaseHeadingref.once('value').then(datasnapshot => {
this.setState({
countrydata: datasnapshot.val(),
countryName: countryName,
loading: false
})
});
}
I think that the "countrydata" in a dict not an array.
Try to initialize the it as an empty array.
Array.prototype.push returns the new length of the array after the push, so you are essentially setting the state to a number.
You are not allowed to mutate the array with React state, you need to create a new array containing your new elements:
// When updating state based on current state, use the function form of setState.
this.setState(state => {
countrydata: [...state.countrydata, datasnapshot.val()],
})
This is assuming countryData is indeed an array, which from your screenshot, it appears to not (it seems to be an object), so you may be set something wrong somewhere along the way (or datasnapshot.val()) doesn't contain what you think it contains.
You could do this:
const keys = Object.keys(countryData); // array of the keys ["place_1", ...]
const array = Array(keys.length); // Prepares the output array of the right size
for (let i=0; i<keys.length; i++) {
const country = countryData[keys[i]]; // get the next country object
country.key = keys[i]; // add the key into the object if you need it
array[i] = country; // store the value into the array at index 'i'
}
// array now is [ {key: "place_1", description: "Sigiriya Rock Fortress"}, ...]
this.setState({countryDataArray: array});
You could try something like this. Array.prototype.push().
I have not tested below code.
componentDidMount=async() =>{
const countryCode = this.props.match.params.countryCode;
var countryName = getName(countryCode);
var firebaseHeadingref = firebase.database().ref(countryCode);
const datasnapshot = await firebaseHeadingref.once('value');
this.setState(prevState=>{
...prevState,
countryName,
countrydata: [...prevState.countrydata, datasnapshot.val()],
loading: false,
},()=>console.log("done!"))
}
You need to convert the response data from firebase to an array like this:
componentDidMount() {
const countryCode = this.props.match.params.countryCode;
var countryName = getName(countryCode);
var firebaseHeadingref = firebase.database().ref(countryCode);
firebaseHeadingref.once('value').then(datasnapshot => {
const countryData = datasnapshot.val();
const countryDataArray = [];
for (const key in countryData) {
countryDataArray.push({ key, ...countryData[key]});
}
this.setState({
countrydata: countryDataArray,
countryName: countryName,
loading: false
})
});
}
Use for-in to loop through the object or use Object.keys().
const data = datasnapshot.val();
const countrydata = [];
for (let key in data) {
countrydata.push(data[key])
}
// using Object.keys()
Object.keys(data).forEach((key) => countrydata.push({ [key]: data[key]}))
this.setState({
countrydata
})
const data = {
place1: { name: 'One'},
place2: { name: 'Two'},
place3: { name: 'Three'},
};
const countrydata = [];
for (let key in data) {
countrydata.push({ [key]: data[key] });
}
console.log(countrydata);

Invalid attempt to spread non-iterable instance on an object [duplicate]

This question already has answers here:
Why are Objects not Iterable in JavaScript?
(7 answers)
Closed 3 years ago.
data: [],
...
I load data from API call into data array. Then I try to arrange the data array into a map which can consist of a key, value pairs (value can be itself array) using below.
const dataMap = {};
for (let i = 0; i < data.length; i+=1) {
const key = data[i].product.name;
const value = data[i];
if (key in dataMap) {
dataMap[key].push(value);
} else {
dataMap[key] = [value];
}
}
But when I do the following I get the following error. What I am doing wrong?
{[...dataMap].map(([key, value]) => {}
Invalid attempt to spread non-iterable instance
This is my dataMap
DataMap is correctly calculate but when i iterate using the following code
Object.entries(dataMap).map((key, value) => {
console.log(key);
console.log(value)
})
it prints out the following. Value is some index which i dont understand why ? Value should be an array. My dataMap is a key, value (value is an array)
Your problem has nothing to do with react/react-native, its plain javascript:
dataMap is already an object, so you only can spread its entries.
// An empty object assign.
const dataMap = {};
// Shallow copy
const objShallowCopy = {...dataMap};
Also, you can rewrite your for-loops using reduce():
const dataSource = [
{ product: { name: 1 }, value: 10 },
{ product: { name: 1 }, value: 100 },
{ product: { name: 2 }, value: 30 },
{ product: { name: 2 }, value: 20 }
];
const dataMap = dataSource.reduce((acc, curr) => {
const prodArr = acc[curr.product.name];
return { ...acc, [curr.product.name]: prodArr ? [...prodArr, curr] : [curr] };
}, {});
console.log(dataMap);
Moreover, Object.entries returns an entries array so you need to fix your loggings:
// Bug
Object.entries(dataMap).map((key, value) => {
console.log(key);
console.log(value);
});
// Good
Object.entries(dataMap).map((([key, value]), index) => {
console.log("key", key);
console.log("value", value);
console.log("index", index);
});
dataMap is object, not an array. You cannot do [...dataMap].
You can convert dataMap to arrays of keys with Object.keys(dataMap) or to array of values with Object.values(dataMap)
So erroneous line should look like
Object.keys(dataMap).map(key => /* dataMap[key] will be value */)

Categories