# Filter by multiple options - also only if not empty [closed]

Here's how my json looks like. I'm trying to write a function which filters based on participantCriteria.criteriaType & participantCriteria._id

participantCriteria ": [ {
"_id": "9be6c6299cca48f597fe71bc99c37b2f",
"caption": "XXXXXXXXXXX",
"criteriaType": "YYYYYY",
"inputSources": [{
"_id": "66be4486ffd3431eb60e6ea6326158fe",
"caption": "docId",
"participantCriteriaId": "9be6c6299cca48f597fe71bc99c37b2f",
"referenceId": null,
"type": "identifier"
},
{
"_id": "1ecdf410b3314865be2b52ca9b4c8539",
"caption": "limit",
"participantCriteriaId": "9be6c6299cca48f597fe71bc99c37b2f",
"referenceId": null,
"type": "number"
}
]
},


Here is the function I have written to filter out the JSON above.

filterFunction(id) // returns the above JSON
.then((criteria) => {
let filteredCriteria = (participantType ? criteria.filter(({ criteriaType }) =>
criteriaType === participantType) : criteria); // if participantType is provided, filter the JSON where criteriaType === participantType

filteredCriteria = (participantCriteriaId ? filteredCriteria.filter(({ _id }) =>
_id === participantCriteriaId) : filteredCriteria) // if participantCriteriaId is provided, filter the json where _id === participantCriteriaId
.map(({ _objectId: _id, caption, criteriaType, inputSources }) => ({
_id,
caption,
criteriaType,
inputSources: inputSources
.map(({ _objectId, caption: inputCaption, isLookup, lookupId, picklistId, type }) => {
let inputSourceType = type;
if (type === 'identifier') { inputSourceType = (isLookup && lookupId) ? 'lookup' : 'key'; }
return {
_id: _objectId,
caption: inputCaption,
participantCriteriaId: _id,
referenceId: (lookupId || picklistId) || null,
type: inputSourceType,
};
}),
}));
res.json({
data: {
participantCriteria: filteredCriteria,
},
});
return undefined;
})


Is there a better way to achieve this filtering ? or Maybe a way to chain the two filters I have added above (the lines where I have added comments).

• To begin with, your code snippet is invalid. Second, it's very hard to tell that is code and what is an object literal. Third, maybe you should put some comments in your code explaining what it does. Then, it is much easier to help you. – FreezePhoenix Jul 24 '18 at 19:03
• @FreezePhoenix thanks for the feedback, i have improved it adding comments to relevant section and removing the wrong code snippet – Ajay Kumar Ganesh Jul 25 '18 at 0:57
• Your question remains unclear. Could you include an example of how you'd use the filters, including the result set? – dfhwze Aug 20 at 17:30

Is this what you're after?

criteria.filter({ _id, criteriaType } => (
(!participantType || participantType === criteriaType)
&&
(!participantCriteriaId || participantCriteriaId === _id)
));


If participantType is empty, it will be coerced to true by the negation, which short-circuits the || operator, so it won't check the right-hand side of the condition. Same for participantCriteriaId.

Note: This type of condition is a common pattern in boolean logic. Generally speaking, conditions that can be phrased as:

If A is true, then check if B is true; otherwise, ignore this condition

Can be transcribed as:

(not A) or B

Which in code is:

!a || b


In your case, the condition is "if the search filter is populated, then check for equality, otherwise ignore", which is transcribed as !filter || property === filter.