How can I add new 2 properties inside the array of objects? Those 2 properties should be added for every object inside the array. Here is the function:
selectTag(selectedProduct, selectedTag) {
this.selectedProducts.filter(item => {
item.id === selectedProduct.id
})
.map(item => {
item.tagId=selectedTag.id, item.tagTitle = selectedTag.title
})
},
dropdown
<b-dropdown aria-role="list">
<b-button
icon-right="caret-down"
class="ToolbarButton"
size="is-small"
>
<span> {{ selectedProduct.tagTitle }} </span>
</b-button>
<b-dropdownitem
v-for="selectedTag in selectedProduct.tags"
:key="selectedTag.id"
aria-role="listitem"
#click="selectTag(selectedProduct, selectedTag)"
>
{{ selectedTag.title }}
</b-dropdownItem>
I tried above function but it didn't work. map method should be fixed. I am trying to add tagId and tagTitle properties which will get value from drop down selection for every product row... How can be it fixed?
The map function indeed is wrong, you don't return anything, it should be like this:
.map(item => ({
...item,
tagId: selectedTag.id,
tagTitle: selectedTag.title
}))
or
.map(item => {
return {
...item,
tagId: selectedTag.id,
tagTitle: selectedTag.title
}
})
you can loop on the object and add your properties:
for(let obj of array) {
obj[key1] = value1;
obj[key2] = value2;
}
If this is in Vue.js, you cannot add properties to an object conventionally, as it will not be reactive. You need to use Vue.set:
selectTag: function(selectedProduct, selectedTag) {
for (var i = 0; i < this.selectedProducts.length; i++) {
if (this.selectedProducts[i].id === selectedProduct.id) {
this.$set(this.selectedProducts[i], "tagId", selectedTag.id);
this.$set(this.selectedProducts[i], "tagTitle", selectedTag.title);
}
}
}
Try this
var arr =[
{id: 1, turnName: "10_00_am"},
{id: 2, turnName: "10_00_am"},
{id: 3, turnName: "11_00_am"}
];
const addProps = (x) => {
x.prop1 = 'Alaska';
x.prop2 = 'Canada';
return x;
}
var newArr = arr.map(x => addProps(x));
console.log(newArr);
From the function you show, point out that the filter needs to store its result in some variable, since filter does not mutate the array in which it is executed. mapping doesn't work because you have to copy the object and then extend the new properties
If I understood your question correctly, please try the following example
const object = {
selectTag(selectedProduct, selectedTag) {
const data = this.selectedProducts.filter((item) => {
item.id === selectedProduct.id;
});
return data.map((entry) => ({
...entry,
tagId: selectedTag.id,
tagTitle: selectedTag.title,
}));
},
};
Use .map with object spread syntax.
.map(item => ({
...item,
item.tagId: selectedTag.id, item.tagTitle: selectedTag.title
}))
You can use ES6 object spread syntax to return a new updated item from map function.
Also, the object properties can be destructured in the function parameters itself to make it look concise and neat.
selectTag(({id}), ({id: tagId, title: tagTitle})) {
this.selectedProducts.filter(item => item.id === id)
.map(item => ({...item, tagId, tagTitle}))
}
Related
I am storing the prev values in an array of objects, for example [{ActFollow: 'BlN'},{ActSendGift: 'BlY'},{ActSubscribe: 'BlY'}] I want to store the key and values in an object like this {ActFollow: 'BlN',ActSendGift: 'BlY', ActSubscribe: 'BlY'}
const [activityTypes, setActivityTypes] = useState<any>([]); // state
.then((response: any) => {
setActivityTypes((oldArray: any) => [
...oldArray,
{[item.channelSettingTypeId]: response.settingValue},
]);
});
How about this, if the nesting is only one level deep
const data = [{ActFollow: 'BlN',ActSendGift: 'BlY', ActSubscribe: 'BlY'}]
console.log([{...data[0],"hey" : "world"}])
const items = [{ActFollow: 'BlN'},{ActSendGift: 'BlY'},{ActSubscribe: 'BlY'}]
let object = {}
items.forEach(item=>{
for (const [key, value] of Object.entries(item)) {
object = {
...object,
[key]: value
}
}
})
console.log(object)
You can use this simple idea in React also. Just hold on the default empty object in state and update the object.
You can reduce the array of objects into an object.
You can do it by spreading (...) the current object into the resultant object, as shown below:
const
arrOfObjs = [{ ActFollow: "BlN" }, { ActSendGift: "BlY" }, { ActSubscribe: "BlY" }],
obj = arrOfObjs.reduce((res, o) => ({ ...res, ...o }), {});
console.log(obj);
You can also do it using Object.assign, as shown below:
const
arrOfObjs = [{ ActFollow: "BlN" }, { ActSendGift: "BlY" }, { ActSubscribe: "BlY" }],
obj = arrOfObjs.reduce((res, o) => Object.assign(res, o), {});
console.log(obj);
Use Spread Operator
const items = [{ActFollow: 'BlN', Anurag: 26},{ActSendGift: 'BlY'},{ActSubscribe: 'BlY'}]
let obj ={}
items.forEach((item) => {
obj = {
...obj,
...item
}
})
console.log(obj)
I have an array of object, I want to add key in my specifi object of array when Id is matched. I have tried this:
this.data.forEach(value => {
if (value.Id === attachmentDataId) {
AttachmentTypeId: this.attachmentRecord.AttachmentType;
}
});
But it's not working and it's not giving any error also
Try this out :
let data = [{ id: 1 }, { id: 5 }];
const attachmentDataId = 5;
const attachmentRecord = { AttachmentType: "AttachmentType" };
data.forEach(value => {
if (value.id === attachmentDataId) {
value.AttachmentTypeId = attachmentRecord.AttachmentType;
}
});
The stackblitz example: https://stackblitz.com/edit/js-nrhouh
You could use the index parameter of forEach function to access the specific object of the array.
this.data.forEach((value, i) => {
if (value.Id === attachmentDataId) {
this.data[i] = {
...this.data[i],
AttachmentTypeId: this.attachmentRecord.AttachmentType
};
}
});
Inside the if block, you could also instead do
this.data[i]['AttachmentTypeId'] = this.attachmentRecord.AttachmentType;
I just find using the spread operator cleaner.
use javascript map() method.
Map() return a new array, it takes a callback, iterates on each element in that array
const updatedData = data.map(res => {
if(res.id === attachmentDataId) {
res.AttachmentTypeId = attachmentRecord.AttachmentType;
}
return res
})
I have a list of object
let table = [{id:4,val:"21321"},{id:5,val:"435345"},{id:6,val:"345345"}]
I want to rename the id value after removing an object from the list which has a specific id value(for example id:5)
I am using array filter method
table.filter((element,index)=>{
if(element.id!==5){
element.id=index
return element
}else{
index+1
}
return null
})
I am expecting a return value
[{id: 0,val: "21321"},{id: 1,val: "345345"}]
but i am getting this
[{id: 0, val: "21321"},{id: 2, val: "345345"}]
Note: I know i can use filter method to remove the specific object and than use map method to rename the id value but i want a solution where i have to use only one arrow function
You can use array#reduce to update the indexes and remove elements with given id. For the matched id element, simply return the accumulator and for other, add new object with val and updated id.
const data = [{ id: 4, val: "21321" }, { id: 5, val: "435345" }, { id: 6, val: "345345" }],
result = data.reduce((res, {id, val}) => {
if(id === 5) {
return res;
}
res.push({id: res.length + 1, val});
return res;
}, []);
console.log(result)
This would do it:
let table = [[{id:4,val:"21321"},{id:5,val:"435345"},{id:6,val:"345345"}]];
let res=table[0].reduce((a,c)=>{if(c.id!=5){
c.id=a.length;
a.push(c)
}
return a}, []);
console.log([res])
The only way to do it with "a single arrow function" is using .reduce().
Here is an extremely shortened (one-liner) version of the same:
let res=table[0].reduce((a,c)=>(c.id!=5 && a.push(c.id=a.length,c),a),[]);
Actually, I was a bit premature with my remark about the "only possible solution". Here is a modified version of your approach using .filter() in combination with an IIFE ("immediately invoked functional expression"):
table = [[{id:4,val:"21321"},{id:5,val:"435345"},{id:6,val:"345345"}]];
res= [ (i=>table[0].filter((element,index)=>{
if(element.id!==5){
element.id=i++
return element
} }))(0) ];
console.log(res)
This IIFE is a simple way of introducing a persistent local variable i without polluting the global name space. But, stricly speaking, by doing that I have introduced a second "arrow function" ...
It probably is not the best practice to use filter and also alter the objects at the same time. But you would need to keep track of the count as you filter.
let table = [[{id:4,val:"21321"},{id:5,val:"435345"},{id:6,val:"345345"}]]
const removeReorder = (data, id) => {
var count = 0;
return data.filter(obj => {
if (obj.id !== id) {
obj.id = count++;
return true;
}
return false;
});
}
console.log(removeReorder(table[0], 5));
It is possible to achieve desired result by using reduce method:
const result = table.reduce((a, c) => {
let nestedArray = [];
c.forEach(el => {
if (el.id != id)
nestedArray.push({ id: nestedArray.length, val: el.val });
});
a.push(nestedArray);
return a;
}, [])
An example:
let table = [[{ id: 4, val: "21321" }, { id: 5, val: "435345" }, { id: 6, val: "345345" }]]
let id = 5;
const result = table.reduce((a, c) => {
let nestedArray = [];
c.forEach(el => {
if (el.id != id)
nestedArray.push({ id: nestedArray.length, val: el.val });
});
a.push(nestedArray);
return a;
}, [])
console.log(result);
The main issue in your code is filter method is not returning boolean value. Use the filter method to filter items and then use map to alter object.
let table = [
[
{ id: 4, val: "21321" },
{ id: 5, val: "435345" },
{ id: 6, val: "345345" },
],
];
const res = table[0]
.filter(({ id }) => id !== 5)
.map(({ val }, i) => ({ id: i, val }));
console.log(res)
Alternatively, using forEach with one iteration
let table = [[{id:4,val:"21321"},{id:5,val:"435345"},{id:6,val:"345345"}]]
const res = [];
let i = 0;
table[0].forEach(({id, val}) => id !== 5 && res.push({id: i++, val}));
console.log(res)
I receive from an ajax call an array of object and some of them are the same, so i want want to push only unique objects in an another array.
receivedArray = [{name:italy, id:67},{name:italy, id:67},{name:france, id:89}]
and i want that :
myArray = [{name:italy, id:67},{name:france, id:89}]
how can i do that ?
Use reduce & findIndex method. findIndex will return the index of the object if the accumulator array already have an object where the id matches. If index is -1 which mean that accumulator array does not have that object.In that case add the array to the accumulator array
let receivedArray = [{
name: 'italy',
id: 67
}, {
name: 'italy',
id: 67
}, {
name: 'france',
id: 89
}]
let myArray = receivedArray.reduce(function(acc, curr) {
let findIndex = acc.findIndex(function(item) {
return item.id === curr.id;
})
if (findIndex === -1) {
acc.push(curr)
}
return acc;
}, [])
console.log(myArray)
You can use filter and Set to do something like this perhaps:
receivedArray = [{name:'italy', id:67},{name:'italy', id:67},{name:'france', id:89}]
mySet = new Set();
myArray = receivedArray.filter(e => {
if (mySet.has(e['id'])) {
return false;
} else {
mySet.add(e['id']);
return true;
}
})
console.log(myArray);
This can be easily solved in es6:
const receivedArray = [{name:'italy', id:67},{name:'italy', id:67},{name:'france', id:89}]
const newArr = receivedArray.filter((item, index, self) =>
index === self.findIndex((i) => (
i.id === item.id && i.name === item.name
))
)
console.log(newArr)
I'm trying to add some behavior exclusively to the last item in a list in Cycle.js. I tried to use cycle-onionify to make a collection like so:
const List = makeCollection({
item: Child,
itemKey: (childState, index) => String(index),
itemScope: key => key,
collectSinks: instances => {
return {
onion: instances.pickMerge('onion'),
DOM: instances.pickCombine('DOM')
.map(itemVNodes => ul(itemVNodes))
}
}
});
I understand that lenses can be used to share state between components, but there doesn't seem to be a way to use lenses with a collection. I'm thinking I could pass the Collection length to the children so I could compare it with an id.
Is there something I am missing?
You can use lenses with makeCollection. Remember it returns a normal Cycle.js component that you can isolate. So if you want to add a boolean isLast you can do this like this:
function omit(obj, key) {
let tmp = { ...obj }; //Copy the object first
delete tmp[key];
return tmp;
}
const listLens = {
get: stateArray => stateArray.slice(0, -1).concat({
...stateArray[stateArray.length - 1],
isLast: true
}),
set: (stateArray, mappedArray) => mappedArray.slice(0, -1)
.concat(omit(mappedArray[mappedArray.length - 1], 'isLast'))
};
const List = isolate(
makeCollection({
item: Child,
itemKey: (childState, index) => String(index),
itemScope: key => key,
collectSinks: instances => ({
onion: instances.pickMerge('onion'),
DOM: instances.pickCombine('DOM')
.map(itemVNodes => ul(itemVNodes))
})
}),
{ onion: listLens, '*': null }
);
As a side note, if you want to apply a lens on each individual item, you can do so too, with the itemScope property. For example
itemScope: key => ({ onion: myLens, '*': key })