Reputation: 10828
I want to return true if all the product contain Done
in the statusLog
array. If any product does not contain Done
in the statusLog
then it should return false. Some product may not have statusLog
property which mean it should return false.
The code seem to work fine, but I felt there must be a better way to refactor this. If "Done" not found from the first product then it should skip the loop as it no need to keep looping. How can that be done?
data={"id":123,"products":[{"id":1,"name":"Item 1","statusLog":[{"name":"New"},{"name":"Done"}]},{"id":2,"name":"Item 2","statusLog":[{"name":"New"},{"name":"Done"}]},{"id":3,"name":"Item 3","statusLog":[{"name":"Pending"},{"name":"Dones"}]},]}
var hasDone = 0;
data.products.forEach((product) => {
if (product.statusLog) {
if (product.statusLog.some((status) => {
return status.name == "Done"
})) {
hasDone++
}
}
});
if (hasDone != data.products.length) {
console.log("All products has Done Status")
}
Demo: https://jsfiddle.net/bdrve3xs/18/
Upvotes: 0
Views: 84
Reputation: 87231
You could use filter
and check its length.
When done like this, you also get the "not done" ones in return.
Stack snippet
data = {
"id": 123,
"products": [{
"id": 1,
"name": "Item 1",
"statusLog": [{ "name": "New" }, { "name": "Done" }]
},
{
"id": 2,
"name": "Item 2",
"statusLog": [{ "name": "New" }, { "name": "Done" }]
},
{
"id": 3,
"name": "Item 3",
"statusLog": [{ "name": "Pending" }, { "name": "Dones" }]
},
]
}
var not_done = data.products.filter(p => {
if (!p.statusLog || !p.statusLog.some(s => s.name === "Done")) return p;
});
if (not_done.length > 0) {
console.log('These/This is not "Done" yet', not_done)
}
Upvotes: 1
Reputation: 141877
You can use Array.prototype.every
const allHaveDone = data.products.every(
product => (product.statusLog || []).some( status => status.name === "Done" )
);
if ( allHaveDone ) {
console.log("All products has Done Status")
}
Upvotes: 4