how to add element to object in array javascript - javascript

I have an array of objects and it is structured as so:
let array1 = [{}]
array1.push({
title: 'myTitle1',
extendedProps: {
field1: 'hello'
}
})
now what I am trying is do an axios.get request and use the data returned to add a new element into array1. I am successfully retrieving the data from the axios request, however, when I try to push the data: res.data[i]._doc.userIsReg, like so:
array1.push({
...array1,
extendedProps: {
...array1.extendedProps,
userIsReg: true
}
})
as you can see, I am using the spread functionaluty to include the current data from array1 into the array and then I try to append a new element userIsReg to the object extendedProps. Now, I assumed this would work, however, when I do this, it creates new object entries within the array and includes everything from inside the array currently (from spread functionality) and adds new entries with the userIsReg in there.
so to be more clear, I start with this:
[{
title: 'myTitle1',
extendedProps: {
field1: 'hello'
}
},
{
title: 'myTitle2',
extendedProps: {
field1: 'hello2'
}
},
]
and then once i do the array1.push with the spread functionality, i get this:
[{
title: 'myTitle1',
extendedProps: {
field1: 'hello'
}
},
{
title: 'myTitle2',
extendedProps: {
field1: 'hello2'
}
},
{
title: 'myTitle1',
extendedProps: {
field1: 'hello',
userIsReg: true
}
},
{
title: 'myTitle2',
extendedProps: {
field1: 'hello2',
userIsReg: true
}
},
]
so basically doubles everything up, instead of appending it to the current array. how would i fix this?

You can do something like following once you have response
array1.map(element => ({...element, userIsReg: true}))
It will add userIsReg flag to each object of your array.
Now as you want it inside extendedProps, you can use following
array1.map(element => (
{...element,
extendedProps: {
...element.extendedProps,
userIsReg: true
}}))

as you defined your array in let type you can do it in this way:
array1 = [...array1.filter(item=> item.title === selected_item.title ),{
...selected_item,userIsReg: true
}]
what I did is to just remove the previous element and add a new one with a new value
if you want to preserve order of array you can sort that

Try this way :
let array1 = [{
title: 'myTitle1',
extendedProps: {
field1: 'hello'
}
},
{
title: 'myTitle2',
extendedProps: {
field1: 'hello2'
}
}];
array1.forEach(obj => {
obj.extendedProps['userIsReg'] = true // this value is coming from API
});
console.log(array1);

Related

How to map JSON Object to array with keys in javascript

There's about million questions (and answers) out there on this topic, but none of them are doing what I need to do. I have a JSON object where the value for each key is an object. I want to convert this to an array and maintain the top level keys.
{
"someKey1": {
active: true,
name: "foo"
},
"someKey2": {
active: false,
name: "bar"
}
}
If I use Object.keys() I get the top level keys, but not their values. If I use Object.values() I get an array with all the values, but not their keys. I'm trying to use keys and map, but am only getting the values returned:
const data = {
"someKey1": {
active: true,
name: "foo"
},
"someKey2": {
active: false,
name: "bar"
}
}
const items = Object.keys(data).map(function(key) {
return data[key];
});
// returns [{active: true, name: foo},{active: false, name: bar}]
Is there a way to get both? I want to get an array I can iterate over that looks something like this:
[{
key: someKey1,
active: true,
name: "foo"
},
{
key: someKey2,
active: true,
name: "foo"
}]
OR
[
"someKey1": {
active: true,
name: "foo"
},
"someKey2": {
active: false,
name: "bar"
}
]
I think you are going in the right direction, if you want to add the "key" property you have to map the properties manually and for the second option since you don't need the "key" property it can be done a little bit more elegantly:
For the first option:
Object.keys(data).map(v => ({
key: v,
...data[v]
}));
For the second option even simpler:
Object.keys(data).map(v => ({[v]: {...data[v]}}))
You can easily map your data to a new object:
Object.keys(data).map(key => ({ ...data[key], "key": key }));

Filtering and maping in nested arrays

My task is to filter objects by values in nested arrays. like in example below:
const array = [
{
authorId: '62222a1cea00a0601f200142',
description: [
[
{
title: 'English description',
paragraph: 'And english paragraph!!!!',
},
],
[
{
title: 'some title!!!',
paragraph: 'some para!!',
},
],
],
removed: false,
status: 'NEW',
},
{
authorId: '621f97562511255efa0f135e',
description: [
[
{
title: 'EEEE',
paragraph: 'aaaa',
},
],
],
removed: false,
status: 'NEW',
},
{
description: [
[
{
title: 'TEST',
paragraph: 'TESR',
},
],
],
removed: false,
status: 'NEW',
},
{
authorId: '621f97432511255efa0f135c',
description: [
[
{
title: 'My task',
paragraph: 'Parapgraph 19',
},
],
],
removed: false,
status: 'NEW',
},
]
my expected results is something like that, based on search input, which is conts searchInput
const searchInput = "par"
const array = [
{
authorId: '62222a1200142',
description: [
[
{
title: 'English description',
paragraph: 'And english paragraph!!!!',
},
],
[
{
title: 'some title!!!',
paragraph: 'some para!!',
},
],
],
removed: false,
status: 'NEW',
},
{
authorId: '6a000142',
description: [
[
{
title: 'TEST',
paragraph: 'paragraph one',
},
],
],
removed: false,
status: 'NEW',
},
]
Ive already try something like this:
const results = array?.map((el) => el?.description.map((i) => i.map((item) => item.paragraph))).filter((description) =>description.toString().toLowerCase().includes(searchValue))
But it return only arrays with paragraphs and i expected to filter whole objects, with all data, not only strings
You need to put the map inside the filter, so your data isn't modified. You use first map the description paragraphs into an array and check if all the values of the paragraphs includes the searched param.
const searchValue = 'para';
const array = [{authorId: '62222a1cea00a0601f200142',description: [[{title: 'English description',paragraph: 'And english paragraph!!!!',},],[{title: 'some title!!!',paragraph: 'some para!!',},],],removed: false,status: 'NEW',},{authorId: '621f97562511255efa0f135e',description: [[{title: 'EEEE',paragraph: 'aaaa',},],],removed: false,status: 'NEW',},{description: [[{title: 'TEST',paragraph: 'TESR',},],],removed: false,status: 'NEW',},{authorId: '621f97432511255efa0f135c',description: [[{title: 'My task',paragraph: 'Parapgraph 19',},],],removed: false,status: 'NEW',},];
const results = array.filter(el => {
return el.description
.map(i => {
return i.map(item => item.paragraph)
})
.every((description) => {
return description.toString().toLowerCase().includes(searchValue)
})
});
console.log(results);
I didn't tested the function, however it should work. Put the questionmarks when needed.
I think the filter should be on the array itself, since that is what you expect to be the result.
I used the some function to resolve the arrays in the object.
array?.filter(el=>el?.description.some(el2=>el2.some(el3=>el3?.paragraph.toString().toLowerCase().includes(searchValue))))
It's easier to understand if you don't have everything on one line.
Use filter to return a new array of objects where the description (inner) array has an at leasr one object that contains a paragraph containing the query.
const array=[{authorId:"62222a1cea00a0601f200142",description:[[{title:"English description",paragraph:"And english paragraph!!!!"}],[{title:"some title!!!",paragraph:"some para!!"}]],removed:!1,status:"NEW"},{authorId:"621f97562511255efa0f135e",description:[[{title:"EEEE",paragraph:"aaaa"}]],removed:!1,status:"NEW"},{description:[[{title:"TEST",paragraph:"TESR"}]],removed:!1,status:"NEW"},{authorId:"621f97432511255efa0f135c",description:[[{title:"My task",paragraph:"Parapgraph 19"}]],removed:!1,status:"NEW"}];
const query = 'par';
const out = array.filter(outer => {
// Return an object when the inner array
// of the function has some object that
// contains a paragraph containing the query
return outer.description.some(arr => {
return arr.some(inner => {
return inner.paragraph
.toLowerCase()
.includes(query);
});
});
});
console.log(out);
Additional documentation
some
have you tried .reduce()? It is combination of .map() and .filter() as you can see here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce
Takes some time to get into .reduce(), but once you get it, you will like it!

Map array of objects into new groups

I have an object with two arrays of objects being returned from an API. I need to try to map this into a new array of objects so I can group the data for the Vue v-select component. CodePen Example
fields: {
current: [
{
name: 'Date'
},
{
name: 'Time'
}
],
previous: [
{
name: 'Birthday'
},
{
name: 'Comments'
}
]
},
How can I map this into a new array of objects that looks like this?
grouped: [
{
group: "Current",
},
{
name: "Date"
},
{
name: "Time"
},
{
group: "Previous"
},
{
name: "Birthday"
},
{
name: "Comments"
},
]
Use Object.entries() to get the groups, and their values, and map them using Array.flatMap(). Create the group's object, and add it to an array with the group's items.
const flattenGroups = fields =>
Object.entries(fields)
.flatMap(([group, items]) => [{ group }, ...items])
const fields = {"current":[{"name":"Date"},{"name":"Time"}],"previous":[{"name":"Birthday"},{"name":"Comments"}]}
const result = flattenGroups(fields)
console.log(result)

Recursively replacing values in an object

Say I have an object that looks like this:
{
_id: ObjectID(1234),
name: 'Corvid',
friends: [{
name: 'Magpie',
friends: [{
name: 'Raven'
}, {
name: 'Jackdaw',
friends: [{
name: Friends.ALL_FRIENDS
}]
}]
}, {
name: 'Jay'
}]
}
Essentially, what I am trying to do is, for every entry in list of friends, replace the current object with the result of Friends.findOne({ name: obj.name }).
I am easy able to iterate through the structure like so.
function populate(obj=friends) {
if (obj.friends) {
return populate(obj.friends);
}
return friends.findOne({ name: obj.name });
}
However, what I am having trouble with is replacing that object at that specific area. How would one go about doing this?

ImmutableJS - update value in a List

I have a Map like this (in ImmutableJS):
{arrayOfValues: [
{one: {inside: 'first in array'}},
{one: {inside: 'second in array'}}
]}
And I want to update the value "inside" in the second entry in the "arrayOfValues" array. How can I do it? This is what I have now and it says "Uncaught Error: invalid keyPath"
theMap.update('arrayOfValues',(list)=>{
return list.setIn([1,'one','inside'],'updated value');
})
I also tried directly this and it didn't work:
theMap.setIn(['arrayOfValues',1,'one','inside'],'updated value');
After several hours of looking for the solution, I appreciate any help. Thank you.
What you are doing is correct (see this JSBin).
const orig = Immutable.fromJS({
arrayOfValues: [
{ one: { inside: 'first in array' } },
{ one: { inside: 'second in array' } },
]
});
const updated = orig.setIn(['arrayOfValues', 1, 'one', 'inside'], 'updated value');
console.log(updated.toJS());
// {
// arrayOfValues: [
// { one: { inside: 'first in array' } },
// { one: { inside: 'second in array' } },
// ]
// }
When you call orig.setIn(), it doesn't modify orig directly. That's the whole purpose of this Immutable library. It doesn't mutate the existing data but creates a new one from the existing one.
Your setIn example works as you should see in this plunkr:
http://plnkr.co/edit/1uXTWtKlykeuU6vB3xVO?p=preview
Perhaps you are assuming the value of theMap will be changed as a result of the setIn?
As these structures are immutable, you must capture the modified value in a new variable as var theMap2 = theMap.setIn(['arrayOfValues',1,'one','inside'],'updated value');
activePane is the index of Object in Array(List) that I had to modify
case CHANGE_SERVICE:
var obj = {
title: '1212121 Tab',
service: '',
tagName: '',
preDefinedApi: '',
methodType: '',
url: '',
urlParams: [{
label: '',
name: '',
value: '',
}],
headers: [{
label: '',
name: '',
value: '',
}],
};
var activePane = state.get('activePane');
var panes = state.setIn(['panes', activePane, 'service'], action.val);
return state.setIn(['panes', activePane, 'service'], action.val);

Categories