I am trying to search through an array of objects using Underscore.js, but I can't seem to target the one I want.
console.log(_.findWhere(response.data, { TaskCategory: { TaskCategoryId: $routeParams.TaskCategory } }));
However, this is returning undefined
$routeParams.TaskCategory
is equal to 301
This is an example of the objects inside the array I am searching. This data is represented by data.response
[{
"TaskCategory": {
"TaskCategoryId": 201,
"TaskName": "TaskName"
},
"TaskCount": 1,
"Tasks": [{
"EventTypeId": 201,
"EventName": "Event Driver",
"EventDate": "0001-01-01T00:00:00",
"EventId": "00000000-0000-0000-0000-000000000000",
}]
},
{
"TaskCategory": {
"TaskCategoryId": 301,
"TaskName": "TaskName"
},
"TaskCount": 1,
"Tasks": [{
"EventTypeId": 201,
"EventName": "Event Driver",
"EventDate": "0001-01-01T00:00:00",
"EventId": "00000000-0000-0000-0000-000000000000",
}]
}]
So I want the second object in that array using the TaskCategory.TaskCategoryId
, is it possible to get it using Underscore?
Answer: Use the find() Method You can simply use the find() method to find an object by a property value in an array of objects in JavaScript. The find() method returns the first element in the given array that satisfies the provided testing function. If no values satisfy the testing function, undefined is returned.
The simplest and fastest way to check if an item is present in an array is by using the Array. indexOf() method. This method searches the array for the given item and returns its index. If no item is found, it returns -1.
Use _.find
instead of findWhere:
console.log(_.find(response.data, function(item) {
return item.TaskCategory.TaskCategoryId == $routeParams.TaskCategory;
}));
They are similar, but findWhere
is designed for special cases where you want to match key-value pairs (not useful in your scenario as it involves nested objects). Find
is more general-use, because it lets you provide a function as the predicate.
The source of _.findWhere
/ _.where
is as follows
_.where = function(obj, attrs, first) {
if (_.isEmpty(attrs)) return first ? void 0 : [];
return _[first ? 'find' : 'filter'](obj, function(value) {
for (var key in attrs) {
if (attrs[key] !== value[key]) return false;
}
return true;
});
};
_.findWhere = function(obj, attrs) {
return _.where(obj, attrs, true);
};
As you can see, it performs strict equality rather than deep equality. If you want a deep searching where, this would suffice (untested, unoptimized):
_.whereDeep = function(obj, attrs, first) {
if (_.isEmpty(attrs)) return first ? void 0 : [];
return _[first ? 'find' : 'filter'](obj, function(value) {
for (var key in attrs) {
if (attrs[key] !== value[key] || !(_.isObject(attrs[key]) && _.whereDeep([value[key]], attrs[key], true))) return false;
}
return true;
});
};
_.findWhereDeep = function(obj, attrs) {
return _.whereDeep(obj, attrs, true);
};
And you would be able to use your code, almost unchanged
_.findWhereDeep(response.data, { TaskCategory: { TaskCategoryId: $routeParams.TaskCategory } });
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With