Filter by multiple options - also only if not empty Here's how my json looks like. I'm trying to write a function which filters based on participantCriteria.criteriaType &amp; 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) =&gt; {
  let filteredCriteria = (participantType ? criteria.filter(({ criteriaType }) =&gt;
    criteriaType === participantType) : criteria); // if participantType is provided, filter the JSON where criteriaType === participantType

  filteredCriteria = (participantCriteriaId ? filteredCriteria.filter(({ _id }) =&gt;
    _id === participantCriteriaId) : filteredCriteria) // if participantCriteriaId is provided, filter the json where _id === participantCriteriaId
    .map(({ _objectId: _id, caption, criteriaType, inputSources }) =&gt; ({
      _id,
      caption,
      criteriaType,
      inputSources: inputSources
        .map(({ _objectId, caption: inputCaption, isLookup, lookupId, picklistId, type }) =&gt; {
          let inputSourceType = type;
          if (type === 'identifier') { inputSourceType = (isLookup &amp;&amp; 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).
Is this what you're after?

criteria.filter({ _id, criteriaType } =&gt; (
    (!participantType || participantType === criteriaType)
    &amp;&amp;
    (!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.