Lizz Parody
Lizz Parody

Reputation: 1765

Filtering a nested object in JavaScript using .filter and .reduce

I have this object that are clinics, the key is the id of the clinic, and it has an id and invitations:

const clinics = {
    "a0CW0000001K2F8MAK": {
        "id": "a0CW0000001K2F8MAK",
        "invitations": {
            "56205": {
              "id": "56205",
              "status": "Confirmed",
          },
        }
    },
    "a0CW00000026gjsMAA": {
        "id": "a0CW00000026gjsMAA",
        "invitations": {}
    },
    "a0CW00000026gjTMAQ": {
        "id": "a0CW00000026gjTMAQ",
        "invitations": {
            "56445": {
              "id": "56445",
              "status": "Cancelled",
          },
        }
    },
    "a0CW00000026gipMAA": {
        "id": "a0CW00000026gipMAA",
        "invitations": {
            "56447": {
                "id": "56447",
                "status": "Confirmed",
            },
            "56448": {
                "id": "56448",
                "status": "Cancelled",
            },
            "56456": {
                "id": "56456",
                "status": "Declined",
            }
        }
    },
    "a0CW00000026gjOMAQ": {
        "id": "a0CW00000026gjOMAQ",
        "invitations": {}
    },
    "a0CW00000026gjnMAA": {
        "id": "a0CW00000026gjnMAA",
        "invitations": {
          "56304": {
              "id": "56304",
              "status": "Pending",
          },
        }
    },
}

And I want to return the object only if the invitation -> status is equal to "Cancelled", there could be more than one invitation, and if any of the invitations is cancelled, I need to return that object, in this case, to return:

const clinics = {
    "a0CW00000026gjTMAQ": {
        "id": "a0CW00000026gjTMAQ",
        "invitations": {
            "56445": {
              "id": "56445",
              "status": "Cancelled",
          },
        }
    },
    "a0CW00000026gipMAA": {
        "id": "a0CW00000026gipMAA",
        "invitations": {
            "56447": {
                "id": "56447",
                "status": "Confirmed",
            },
            "56448": {
                "id": "56448",
                "status": "Cancelled",
            },
            "56456": {
                "id": "56456",
                "status": "Declined",
            }
        }
    },
}

I tried something like this, but it didn't work:

function filterByStatus(clinics) {
  return Object.keys(clinics)
    .filter(clinicId => clinics[clinicId].invitations.status === "Cancelled")
    .reduce((acc, key) => Object.assign(acc, { [key]: clinics[key] }), {});
}

How can I do this? thanks!

Upvotes: 0

Views: 238

Answers (1)

CertainPerformance
CertainPerformance

Reputation: 370809

Check if some of the invitations objects values have a status of Cancelled. No need for filter, you can avoid iterating twice by just testing in the reduce function itself:

const clinics={"a0CW0000001K2F8MAK":{"id":"a0CW0000001K2F8MAK","invitations":{"56205":{"id":"56205","status":"Confirmed",},}},"a0CW00000026gjsMAA":{"id":"a0CW00000026gjsMAA","invitations":{}},"a0CW00000026gjTMAQ":{"id":"a0CW00000026gjTMAQ","invitations":{"56445":{"id":"56445","status":"Cancelled",},}},"a0CW00000026gipMAA":{"id":"a0CW00000026gipMAA","invitations":{"56447":{"id":"56447","status":"Confirmed",},"56448":{"id":"56448","status":"Cancelled",},"56456":{"id":"56456","status":"Declined",}}},"a0CW00000026gjOMAQ":{"id":"a0CW00000026gjOMAQ","invitations":{}},"a0CW00000026gjnMAA":{"id":"a0CW00000026gjnMAA","invitations":{"56304":{"id":"56304","status":"Pending",},}},}

console.log(
  Object.entries(clinics).reduce((a, [key, val]) => {
    const { invitations } = val;
    if (Object.values(invitations).some(({ status }) => status === 'Cancelled')) {
      a[key] = val;
    }
    return a;
  }, {})
);

Upvotes: 2

Related Questions