Getting a property of an object within an array - javascript

I use Vue.js and have a method that compares a value from one array with a value from another array.
array1: [{ name: 'test1', somevar: true }, { name: 'test2', somevar: false }]
array2: ['test1', 'test3']
compare() {
//I want to access an object property within an array1
this.array1.forEach((element) => {
if(this.array1.element.name.includes(this.array2[0])) {
// if it is true, I would like to remove that compared value from an array 1
if(this.array2[0] !== -1) {
var index = this.array1.element.name.indexOf(this.array2[0])
this.array1.splice(index, 1)
}
}
I think this part: this.array1.forEach((element) is incorrect. How can I access property of that object?

array1 is an array, not an object, so accessing this.array1.element won't work. Simply refrence the element as the parmeter given to forEach instead.
Also, the function passed forEach accepts another argument: the second argument represents the current element's index, so there's no need to search for indexOf.
But, even better than those tweaks, it would be more appropriate to use filter in this situation:
const obj = {
array1: [{ name: 'test1', somevar: true }, { name: 'test2', somevar: false }],
array2: ['test1', 'test3'],
compare() {
obj.array1 = obj.array1.filter(({ name }) => (
!obj.array2.includes(name)
))
}
}
obj.compare();
console.log(obj.array1);

Related

Javascript : Modify object and add new index to a property

My object is something like:
let items =
[
{
"creationTimeStamp": "2022-05-31T17:04:28.000Z",
"modifiedTimeStamp": "2022-05-31T17:04:28.000Z",
"locations": [
{
"id": "5ao",
"name": "Store1"
}
],
"typeId": "Lead"
}
]
I am trying to push the following object into the locations property:
{
"id": "9a0",
"name": "Store2"
}
I have tried doing
items1 = [];
for (var i = 0; i < items.length; i++) {
items1.id = "9a0";
items1.name = "Store2";
//9 is some static index value added
Object.assign({9 : items1}, items[i].locations);
}
If I console(Object.assign({9 : items1}, items[i].locations)); I can see 2 arrays inside it, but my items locations property is still the same.
My expectation is as below:
[
{
"creationTimeStamp": "2022-05-31T17:04:28.000Z",
"modifiedTimeStamp": "2022-05-31T17:04:28.000Z",
"locations": [
{
"id": "5ao",
"name": "Store1"
},
{
"id": "9a0",
"name": "Store2"
}
],
"typeId": "Lead"
}
]
I also tried to use items[i].locations.push(item1) but then got:
TypeError: Cannot add property 9, object is not extensible
I also tried to assign a new array to items[i].locations, but then got:
TypeError: Cannot assign to read only property 'locations' of object '#'
What can I do to get the desired result?
You seem to expect that the second argument given to Object.assign will be mutated. But it is the first argument that is mutated. That means your .locations is not mutated. Moreover, in comments you indicate that locations cannot be extended and that the property is read-only.
So that means you'll need a complete new object.
Some other remarks:
Don't initialise items1 as an array, since it is supposed to be a plain object.
Declare a variable with const, let or var and avoid implicit global declaration.
It is safer to declare the items1 object inside the loop, so you create a new object each time and don't mutate the same object. For your example code it makes no difference, but it can lead to unexpected behaviour.
As you don't need i for anything else than items[i], and you actually need a complete new structure, use .map instead.
So:
items = items.map(item => {
let obj = {
id: "9a0",
name: "Store2"
};
return {...item, locations: item.locations.concat(obj) };
});
I always think in terms of functions, and of immutability-by-default, so my approach might look like this, with addLocationToAll built atop a simpler addLocation. The code is fairly simple:
const addLocation = (newLoc) => ({locations, ...rest}) =>
({...rest, locations: locations .concat (newLoc)})
const addLocationToAll = (newLoc) => (items) =>
items .map (addLocation (newLoc))
const items = [{creationTimeStamp: "2022-05-31T17:04:28.000Z", modifiedTimeStamp: "2022-05-31T17:04:28.000Z", locations: [{id: "5ao", name: "Store1"}], typeId:"Lead"}]
const newLoc = {id: "9a0", name: "Store2"}
console .log (addLocationToAll (newLoc) (items))
.as-console-wrapper {max-height: 100% !important; top: 0}
items is an array so it must access the first position of the array, which would be the proposed object.
With this, from the proposed object you will extract thelocation attribute and since this is an array, you use the push function to insert the new object
items[0]
// ->
// {
// creationTimeStamp: '2022-05-31T17:04:28.000Z',
// modifiedTimeStamp: '2022-05-31T17:04:28.000Z',
// locations: [ { id: '5ao', name: 'Store1' } ],
// typeId: 'Lead'
// }
I try this:
items[0].locations.push({"id": "9a0", "name": "Store2" })
And now:
items[0]
//->
// {
// creationTimeStamp: '2022-05-31T17:04:28.000Z',
// modifiedTimeStamp: '2022-05-31T17:04:28.000Z',
// locations: [ { id: '5ao', name: 'Store1' }, { id: '9a0', name: 'Store2' }],
// typeId: 'Lead'
// }

Javascript: How to iterate through an array looking for an object value?

I have a js file that is just a an array with the name and type of person. I am trying to write a function in my other file to iterate through that array of objects and return just the object that matches a certain criteria. Here is my code.
person.js
export const persons_options = [
{
name: 'Andrew',
type: 'Athlete',
},
{
name: 'Paul',
type: 'Worker',
},
{
name: 'Phil',
type: 'Developer',
},
]
utils.js
// params initialized already
person_type = params.subType
const name = persons_options.map((option) => {
if(person_type === option.type){
return option.name
}
})
const person = name
The issue is I know map creates a new array so the output is ,,Phil. How would I just return one of the object names instead of all of them.
find() will do the work
let persons_options = [
{
name: 'Andrew',
type: 'Athlete',
},
{
name: 'Paul',
type: 'Worker',
},
{
name: 'Phil',
type: 'Developer',
},
]
let obj = persons_options.find(o => o.type === 'Developer');
//to return name
console.log("name",obj.name);
console.log(obj);
You need to use the find function.
See here the list of functions that you can call on an array:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array#instance_methods
filter might best suit your case if multiple results may be returned.

Remove empty object from array of objects

I have an array of objects and a delete function that pass the index as a parameter but fails to remove the empty object. Objects containing properties can be removed. Does anyone know how to fix it? The example code is shown below.
let array = [
{
id: '1',
name: 'sam',
dateOfBirth: '1998-01-01'
},
{
id: '2',
name: 'chris',
dateOfBirth: '1970-01-01'
},
{
id: '3',
name: 'daisy',
dateOfBirth: '2000-01-01'
},
{}
]
// Objects contain properties can be removed but empty object can not be removed.
const deleteItem = (index) => {
return array.splice(index, 1);
};
Use Array.filter to filter out the items which have no properties
let array = [
{id:"1",name:"sam",dateOfBirth:"1998-01-01"},
{id:"2",name:"chris",dateOfBirth:"1970-01-01"},
{id:"3",name:"daisy",dateOfBirth:"2000-01-01"},
{}
]
const filtered = array.filter(e => Object.keys(e).length)
console.log(filtered)
The above works since Object.keys will return an array of the properties of the object. Getting its length property will get the number of items in the array. If the length property is 0, it is coerced to false (see: Falsy values).

Javascript - how to get just the value of the property after filtering and mapping the array of objects

I am filtering and mapping the array objects that looks like this:
taxonomy:Object
data:Array[2]
0:Object
id:377
name:"Buss"
slug:"buss"
type:"post_tag"
1:Object
My function looks like this:
let tag = this.article.taxonomy.data.filter(function( data ) {
return data.type.includes('tag')
}).map(function(obj) {
return obj.name;
});
return tag;
What I am just wondering is there a way to get from the map function just the string name value, since now it returns ["Buss"], so that don't need to use the index at the end of the function:
return tag[0]
It sounds like you want find, not filter, if you're looking only for one result. find returns the first entry for which the callback returns a truthy value, or undefined if it never does. So:
const obj = this.article.taxonomy.data.find(data => data.type.includes('tag'));
const tag = obj && obj.name; // Note the guard in case no entry matched
return tag; // Will be the name or `undefined`
(Note that I've assumed you can use an arrow function, as you're using let. If not, just replace it with a function function.)
Live Example:
const taxonomy = {
data: [
{
id: 375,
name: "A",
slug: "A",
type: "nope"
},
{
id: 376,
name: "B",
slug: "B",
type: "nor-this"
},
{
id: 377,
name: "Buss",
slug: "buss",
type: "post_tag"
},
{
id: 378,
name: "C",
slug: "C",
type: "blah"
}
]
};
const obj = taxonomy.data.find(data => data.type.includes('tag'));
const tag = obj && obj.name;
console.log(tag);

TypeError: obj[key].includes is not a function when filtering values of an object in an array

I wanted to filter the values in an array of objects by a certain value. When I run the function, I get TypeError: obj[key].includes is not a function. I am using reactjs. What I'm I missing in the function?
var arr = [{
name: 'xyz',
grade: 'x'
}, {
name: 'yaya',
grade: 'x'
}, {
name: 'x',
frade: 'd'
}, {
name: 'a',
grade: 'b'
}];
filterIt(arr, searchKey) {
return arr.filter(obj => Object.keys(obj)
.map(key => obj[key].includes(searchKey)));
}
I got this example from https://stackoverflow.com/a/40890687/5256509 and tried it out
You can't filter array of object like this, because this combination
Object.keys(obj).map(key => obj[key].includes(searchKey))
always provides an array (with true and false values), and any array is truthy. Hence filter doesn't filter anything. You can try something like this:
arr.filter(obj =>
Object.keys(obj)
.some(key => obj[key].includes(searchKey))
);

Categories