I want to hide a button if there is atleast one order or subareas that at least one orders whose status 'ACCEPTED' or 'DONE'.
How can I hide the "Hide me" Menu item when either item has at least one area with order status 'ACCEPTED' OR 'DONE' or at least one area with subareas order with status 'ACCEPTED' or 'DONE'.
Below is the react code with the item I am trying to process
function Parent() {
const item = {
owner: {
id: '1',
cognitoId: '2',
},
areas: [{
id: '1',
orders: [{
id: '1',
status: 'ASSIGNED',
}, {
id: '2',
status: 'ACCEPTED',
}
],
subAreas: [{
id: '1',
orders: [{
id: '4',
status: 'DONE',
}
],
}
]
}, {
id: '2',
orders: [{
id: '3',
status: 'ASSIGNED',
}, {
id: '4',
status: 'ACCEPTED',
}
],
subAreas: [{
id: '2',
orders: [{
id: '5',
status: 'DONE',
}, {
id: '6',
status: 'ACCEPTED',
}
],
}
]
}
]
}
return ({
item && item.owner && item.owner.cognitoId && (
< Menu > Hide me < / Menu > )
});
}
EDIT
strong text
As per the solution provided i have tried like below,
const hasDoneAccepted = () => {
Object
.keys(item)
.some(key =>
(key === 'status' &&
['DONE', 'ACCEPTED'].includes(item[key])) || //error //here
(typeof item[key] == 'object' && //error here
hasDoneAccepted(item[key])) //error here
};
But this gives me error
Element implicitly has any type because expression of type "status" cant be used on index type 'Item'. property status doesnt exist on type 'Item'.
EDIT2strong text
based on solution for typescript implemented like below,
const hasDoneAccepted = (o: any) => {
const output = Object.keys(o).some(
key =>
(key === 'status' && ['DONE', 'ACCEPTED'].indexOf(o[key]) > -1) ||
(typeof o[key] === 'object' && hasDoneAccepted(o[key]))
);
return output;
};
console.log("output***", hasDoneAccepted(item));
this doesnt give any errors but in runtime the app breaks. and in the console i see the error.
"cannnot convert undefined or null to object"
You may traverse recursively (e.g. with Array.prototype.some()) your source object all deep through to find out, whether some key, named status has value either'DONE' or 'ACCEPTED' within nested properties:
const item = {owner:{id:'1',cognitoId:'2',},areas:[{id:'1',orders:[{id:'1',status:'ASSIGNED',},{id:'2',status:'ACCEPTED',}],subAreas:[{id:'1',orders:[{id:'4',status:'DONE',}],}]},{id:'2',orders:[{id:'3',status:'ASSIGNED',},{id:'4',status:'ACCEPTED',}],subAreas:[{id:'2',orders:[{id:'5',status:'DONE',},{id:'6',status:'ACCEPTED',}],}]}]},
hasDoneAccepted = o =>
Object
.keys(o)
.some(key =>
(key == 'status' &&
['DONE', 'ACCEPTED'].includes(o[key])) ||
(typeof o[key] == 'object' &&
hasDoneAccepted(o[key])))
console.log(hasDoneAccepted(item))
So, your conditional rendering may look something, like that:
function Parent() {
const hasDoneAccepted = ..
..
return !!item?.owner?.cognitoId && hasDoneAccepted(item) &&
(<Menu>Hide me</Menu>)
}
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