This question already has answers here:
JavaScript "cannot read property "bar" of undefined [duplicate]
(4 answers)
Closed 4 years ago.
I'm trying to change JSON structure for push to my database
my old JSON :
[
{"name": "nameGallery"},
{"img": "1.jpg"},
{"img": "2.img"}
]
And I want to group "img" variable to "Images" Array like this:
[
{
"name": "nameGallery",
"Images": [
{"img": "1.jpg"},
{"img": "2.img"}
]
}
]
I'm trying to use object.assign to manage it but I don't know why it error.
function getData() {
fetch('text/upload.json').then((res) => res.json())
.then((data) => {
console.log(data);
data = data.map(o => Object.assign({}, o,
{ Images: o.Images.map(({ img }) => ({ img: img })) }
));
})
}
My Result:
In your solution you are calling .map which will create you one array entry for every array entry in your initial data.
As you described, you expect one object as a result and not an array of object. So look at the following :
const data = [{
name: 'nameGallery',
},
{
img: '1.jpg',
},
{
img: '2.img',
},
];
// You want to create a new object using all the others objects
const ret = data.reduce((tmp, x) => {
// If the key below is 'img', we push the object into 'Images'
// void 0 means undefined
if (x.img !== void 0) {
tmp.Images.push(x);
return tmp;
}
// If the key is not 'img'
// We copy the keys into tmp
return {
...tmp,
...x,
};
}, {
// initialize 'Images' key here it won't be undefined
// when pushing the first data
Images: [],
});
console.log(ret);
You can try something like this:
function getData() {
fetch('text/upload.json').then((res) => res.json())
.then((data) => {
const name = data.find(o => !!o.name);
return {
name: name.name,
Images: data.filter(o => !!o.img)
};
})
}
Related
The original data (old) looks like this:
Object {
"pageParams": Array [
undefined,
],
"pages": Array [
Object {
"cursor": 0,
"items": Array [
Object {
"content": "This is a users post!",
"createdAt": "2022-09-03T02:37:10.287Z",
"id": "93d13314-630e-4948-94a4-f75677afa7ba",
"likeCount": 10,
"likedByUser": false,
...
Just need to toggle likedByUser on click. passing in (id,performerId) in flatlist onclick.
Trying to map like this but I don't believe it is returning the original structure for the infinite scroll. need to return old with one changed object.
const likeHandler = (id: string, performerId: string) => {
const LikePostMutation: LikePostInput = {
id: id,
performerProfileId: performerId,
}
mutateLikes.mutateAsync(LikePostMutation).then(() => {
context.setQueryData(['fan.performer.getPostsFeed', {}], (old) => {
if (!old) return old
return old.pages.map((item: { items: any[] }) =>{
item?.items.map((item) => {
if (item?.id === id) {
let newItem = {
...item,
likedByUser: !item.likedByUser,
}
return { newItem }
}
}),
}
)
})
})
}
The error message TypeError: undefined is not an object (evaluating 'o[Symbol.iterator]') is from flatlist. I think the error message coming from view:
This is the shape of logged data after mapping incorrectly: I need it to be in the pages array and in an outer object.
}
Object {
content": "This is a users post!",
"createdAt": "2022-09-03T02:37:10.287Z",
"id": "93d13314-630e-4948-94a4-f75677afa7ba",
"likeCount": 10,
"likedByUser": true,
...
open to any suggestions on how to get better at this.
when doing immutable updates to arrays, you need to map over each item and return the same structure. infinite query structure is nested so it gets a bit boilerplat-y, but this should work:
context.setQueryData(['fan.performer.getPostsFeed', {}], (old) => {
if (!old) return old
return {
...old,
pages: old.pages.map(page) => ({
...page,
items: page.items.map((item) => {
if (item?.id === id) {
return {
...item,
likedByUser: !item.likedByUser,
}
return item
}
})
})
}
})
if you don't like the deep spreading, take a look at immer
I'd like to refactor a block of code which basically has to map 2 levels to the data I want. The data I want is the value of body in a object that contains ['key'] that has array of objects .
My object looks as follows,
const object = {
"array-one": [
{
id: 1,
body: "need_help",
},
{
id: 2,
body: "no_help",
},
],
}
and below is how I map to get the value of body
const getTheBodyValue = () => Object.keys(object).map(key => {
object[key].map((elem) => {
const { id, body } = elem;
if (body === 'need_help') // do something
if (body === 'no_help') // do something
});
});
is there a more simpler way to achieve the value of body in "array-one" & "array-two"?
You could flat the values from the object and take a single loop.
Object
.values(object)
.flat()
.forEach(({ id, body }) => {
// your code
})
So,
I am receiving the data that has the following information:
{
"data":[
{
"vote_count":22222,
"id":299537,
"ready":false,
},
{
"vote_count":2850,
"id":299534,
"ready":true,
},
]
}
Now I need to make a new object that would contain the same structure but with some properties, ie:
{
"data": [
{
"ready":false,
},
{
"ready":true,
}
]
}
I need the solution that is scalable, imagine having a set of data with 50 properties for example. Also, I did find solutions with objects, but never with array of objects.
Thanks guys, I've been busting my head for three hours now.
You could use destrcuturing and shorthand property names to create new objects like this:
const input={"data":[{"vote_count":22222,"id":299537,"ready":false,},{"vote_count":2850,"id":299534,"ready":true,},]}
const data = input.data.map(({ ready }) => ({ ready }))
console.log({ data })
If you want to get a bunch of properties, you could create an array of properties you need. Then use Object.assign() or reduce to create a subset of each object like this:
const input={"data":[{"vote_count":22222,"id":299537,"ready":false,},{"vote_count":2850,"id":299534,"ready":true,},]}
const properties = ["vote_count", "ready"]
const data = input.data.map(a =>
Object.assign({}, ...properties.map(p => ({ [p]: a[p] })))
)
/* You could also use reduce like this:
input.data.map(a => properties.reduce((r, p) => ({ ...r, [p]: a[p] }), {}))
*/
console.log({ data })
Map the properties you want
var obj1 = {
"data":[
{
"vote_count":22222,
"id":299537,
"ready":false,
},
{
"vote_count":2850,
"id":299534,
"ready":true,
},
]
}
var obj2 = {}
obj2.date = obj1.data.map(data => ({ ready: data.ready}));
console.log(obj2)
You can do it using Array#map method and Array#reduce method
const input = {
"data": [{
"vote_count": 22222,
"id": 299537,
"ready": false,
},
{
"vote_count": 2850,
"id": 299534,
"ready": true,
},
]
}
const extract = ['ready']
const data = input.data.map(o => extract.reduce((obj, k) => (obj[k] = o[k], obj), {}))
console.log({ data })
In my post request I need to pass an array with an object inside it.
when I tried to add new properties inside an object its adding.
but when I tried to add when an object is present inside an array its not adding.
I have sportsvalues as array const sportsValues = [{ ...values }];
I am trying to build something like this, so that I can pass in the api
[
{
"playerName": 3,
"playerHeight": 1
}
]
can you tell me how to fix it.
providing my code snippet below.
export function sports(values) {
const sportsValues = [{ ...values }];
sportsValues.push(playerName:'3');
console.log("sportsValues--->", sportsValues);
// sportsValues.playerName = 3//'';
// sportsValues.playerHeight = 1//'';
console.log("after addition sportsValues--->", sportsValues);
console.log("after deletion sportsValues--->", sportsValues);
return dispatch => {
axios
.post(`${url}/sport`, sportsValues)
.then(() => {
return;
})
.catch(error => {
alert(`Error\n${error}`);
});
};
}
Since sportsValues is an array of objects, you can push new object into it. Check out code below.
const sportsValues = [];
sportsValues.push({
playerName:'3',
playerHeight: 1,
});
console.log(sportsValues);
I don't fully understand what you're trying to do, but here's some pointers:
If you're trying to update the object that's inside the array, you first have to select the object inside the array, then update it's attribute:
sportsValues[0].playerName = 3
although, I recommend building the object correctly first, then passing it to the array, it makes it a little easier to understand in my opinion:
const sportsValues = [];
const firstValue = { ...values };
firstValue.playerName = '3';
sportsValues.push(firstValue);
or
const firstValue = { ...values };
firstValue.playerName = '3';
const sportsValues = [firstValue];
or
const sportsValues = [{
...values,
playername: '3',
}];
if you're trying to add a new object to the array, you can do this:
const sportsValues = [{ ...values }];
sportsValues.push({ playerName: '3' });
etc...
Array.push adds a new item to the array, so in your code, you're going to have 2 items because you assign 1 item at the beginning and then push a new item:
const ar = [];
// []
ar.push('item');
// ['item']
ar.push({ text: 'item 2' });
// ['item', { text: 'item 2' }]
etc...
export function sports(values) {
const sportsValues = [{ ...values }];
sportsValues.push(playerName:'3');
let playerName='3'
sportsValues.playerName= playerName; // you can bind in this way
console.log("sportsValues--->", sportsValues);
return dispatch => {
axios
.post(`${url}/sport`, sportsValues)
.then(() => {
return;
})
.catch(error => {
alert(`Error\n${error}`);
});
};
}
I have attributes of objects of an array that I would like to store in an array. Below is my data.
What I want to do achieve is to store displays name attribute in opt[] so it would look like this opt = ['info1', 'info2', 'info3', ... ]
getEditData (id) {
axios.get('/api/campaign/getEdit/' + id)
.then(response =>{
this.campaign = response.data.campaign;
})
.catch(e=>{
console.log(e.data);
this.error = e.data
})
}
Above snippet is the source of the campaign object
You can use this expression:
campaigns.displays.map( ({name}) => name );
const campaigns = { displays: [{ name: 'info1'}, { name: 'info2'}] };
const result = campaigns.displays.map( ({name}) => name );
console.log(result);
This will display an array containing the property names of each object in the displays array
var data = {
displays: [
{
capacity: 9000,
id: 1,
imei: 44596
}
]
};
data.displays.forEach(function(obj, idx) {
console.log(Object.keys(obj));
});
Object.keys() is what you need