Reputation: 195
I am trying to filter my object with an array of objects inside. Currently, I have this data.
{
tile: "test title",
id: 1,
createdBy: "[email protected]",
comments: "",
taskId: "TK-12345",
schedules: [
{
id: 101,
dateAssigned: "2019-10,-03",
taskStatus: "On track"
},
{
id: 102,
dateAssigned: "2019-10,-03",
taskStatus: "On track"
}
]
},
{
tile: "test title no. 2",
id: 1,
createdBy: "[email protected]",
comments: "",
taskId: "TK-54321",
schedules: [
{
id: 101,
dateAssigned: "2019-09,-03",
taskStatus: "Overdue"
}
]
},
{
tile: "test title no. 3",
id: 1,
createdBy: "[email protected]",
comments: "",
taskId: "TK-99999",
schedules: [
{
id: 103,
dateAssigned: "2019-09,-03",
taskStatus: "Open"
}
]
}
I want to filter only "Open" and "Overdue" items.
this.urgentRequests = this.urgentRequests.filter(a => {
return a.schedules.find(s => s.taskStatus !== 'On track');
});
Currently, it is not working. It is possible to filter and find at the same time?
I am still getting 'On track' items
The expected output gets only data with overdue and open items. But right now its is returning all items including "On track"
{
tile: "test title no. 2",
id: 1,
createdBy: "[email protected]",
comments: "",
taskId: "TK-54321",
schedules: [
{
id: 101,
dateAssigned: "2019-09,-03",
status: "Overdue"
}
]
},
{
tile: "test title no. 3",
id: 1,
createdBy: "[email protected]",
comments: "",
taskId: "TK-99999",
schedules: [
{
id: 103,
dateAssigned: "2019-09,-03",
status: "Open"
}
]
}
Upvotes: 0
Views: 433
Reputation: 2116
I think your code is almost correct,
// Your code
this.urgentRequests = this.urgentRequests.filter(a => {
a.schedules.find(s => s.taskStatus !== 'On track');
});
s.taskStatus
into s.status
instead. If you look closely, the key name is status
.filter
expects a function that return boolean as the input. In your case, your function not returning anything, thus returning undefined (computed to false).So, the code should looks like this:
this.urgentRequests = this.urgentRequests.filter(a => {
return a.schedules.find(s => s.status !== 'On track');
});
Edit: I added code snippet to make sure everything is working. And it does. You can check it below.
const items = [{
tile: "test title",
id: 1,
createdBy: "[email protected]",
comments: "",
taskId: "TK-12345",
schedules: [
{
id: 101,
dateAssigned: "2019-10,-03",
status: "On track"
},
{
id: 102,
dateAssigned: "2019-10,-03",
status: "On track"
}
]
},
{
tile: "test title no. 2",
id: 1,
createdBy: "[email protected]",
comments: "",
taskId: "TK-54321",
schedules: [
{
id: 101,
dateAssigned: "2019-09,-03",
status: "Overdue"
}
]
},
{
tile: "test title no. 3",
id: 1,
createdBy: "[email protected]",
comments: "",
taskId: "TK-99999",
schedules: [
{
id: 103,
dateAssigned: "2019-09,-03",
status: "Open"
}
]
}]
const targets = ["open", "overdue"];
const filterResult = items.filter(item => {
return item.schedules.find(s => targets.includes(s.status.toLowerCase()))
})
console.log("I named the original array into 'items'.");
console.log("I add toLowerCase to make sure it wasn't typing issue.");
console.log("The results are: ", filterResult);
console.log("The result's schedules are: ", filterResult.map(a => a.schedules));
console.log(" No more 'On Track' right :) ");
NB: I'm using several new techniques but the idea is still the same.
Upvotes: 1
Reputation: 8584
You were on the right track, but your outer arrow function was missing a return
and you should use some
instead of find
. You need to use return
if your arrow function has braces around the body; I fixed this by dropping the braces. Also, you wrote taskStatus
instead of status
.
this.urgentRequests.filter(a =>
a.schedules.some(s => s.status !== 'On track'))
Upvotes: 1
Reputation: 10193
Using Array.prototype.reduce
, you can extract filtered items only.
const input = [{
tile: "test title",
id: 1,
createdBy: "[email protected]",
comments: "",
taskId: "TK-12345",
schedules: [
{
id: 101,
dateAssigned: "2019-10,-03",
status: "On track"
},
{
id: 102,
dateAssigned: "2019-10,-03",
status: "On track"
}
]
},
{
tile: "test title no. 2",
id: 1,
createdBy: "[email protected]",
comments: "",
taskId: "TK-54321",
schedules: [
{
id: 101,
dateAssigned: "2019-09,-03",
status: "Overdue"
}
]
},
{
tile: "test title no. 3",
id: 1,
createdBy: "[email protected]",
comments: "",
taskId: "TK-99999",
schedules: [
{
id: 103,
dateAssigned: "2019-09,-03",
status: "Open"
}
]
}];
const output = input.reduce((acc, cur) => {
const schedules = cur.schedules.filter(({status}) => status === 'Open' || status === 'Overdue');
if (schedules.length > 0) {
acc.push({
...cur,
schedules
});
}
return acc;
}, []);
console.log(output);
Upvotes: 2