0

I have a request I receive through a webhook which returns the following object as req.body:

{"appId":"7HPEPVBTZGDCP","merchants":{"6RDH804A896K1":[{"objectId":"O9FN4R9BMKXQ0","type":"UPDATE","ts":1686754357822},{"objectId":"OE87DT9330H7R","type":"UPDATE","ts":1686754358007}]}}

The issue i am having is although I can access the merchants through req.body.merchants, that is a key/value pair with the key being a string and the value being an array as:

{"6RDH804A896K1":[{"objectId":"O9FN4R9BMKXQ0","type":"UPDATE","ts":1686754357822},{"objectId":"OE87DT9330H7R","type":"UPDATE","ts":1686754358007}]}

The issue i am having is that I need a way to access the key of merchants, 6RD8H04A896K1, as well as the value which is:

[{"objectId":"O9FN4R9BMKXQ0","type":"UPDATE","ts":1686754357822},{"objectId":"OE87DT9330H7R","type":"UPDATE","ts":1686754358007}]

I tried the following but had no luck:

        const merchantResponse: { id : value} = req.body.merchants;

but that doesn't seem to work either. Can someone tell me how I can convert this nested key/value pair into a json object and access its values? The issue is I do not have the object key otherwise I could have just called it as:

const merchantResponse = req.body['6RDH804A896K1'];

anyone have a solutions to this problem?

z123
  • 193
  • 1
  • 15

2 Answers2

4

If you need to get the merchants, you know you need to grab it by that key at the very least.

Just get the object values and access the first value.

const req = {
  body: {
    "appId": "7HPEPVBTZGDCP",
    "merchants": {
      "6RDH804A896K1": [{
        "objectId": "O9FN4R9BMKXQ0",
        "type": "UPDATE",
        "ts": 1686754357822
      }, {
        "objectId": "OE87DT9330H7R",
        "type": "UPDATE",
        "ts": 1686754358007
      }]
    }
  }
}

const getNestedData = (root, key) => ({ [key]: Object.values(root[key])[0] });

console.log(getNestedData(req.body, 'merchants'));
.as-console-wrapper { top: 0; max-height: 100% !important; }

TypeScript approach

If you are doing this in TypeScript, you can try:

const req = {
  body: {
    "appId": "7HPEPVBTZGDCP",
    "merchants": {
      "6RDH804A896K1": [{
        "objectId": "O9FN4R9BMKXQ0",
        "type": "UPDATE",
        "ts": 1686754357822
      }, {
        "objectId": "OE87DT9330H7R",
        "type": "UPDATE",
        "ts": 1686754358007
      }]
    }
  }
};

type UpdateType = 'CREATE' | 'DELETE' | 'UPDATE';

interface Merchant {
  objectId: string,
  type: UpdateType,
  ts: number
};

function unwrapMerchants(root: object): Merchant[] {
  return Object.values(root)[0] as Merchant[];
}

const pair = { merchants: unwrapMerchants(req.body.merchants) };

console.log(pair);

After seeing your answer to your question, you can just pop the first entry off of the entries and destructure they key-value pair into variables like so:

const req = {
  body: {
    "appId": "7HPEPVBTZGDCP",
    "merchants": {
      "6RDH804A896K1": [{
        "objectId": "O9FN4R9BMKXQ0",
        "type": "UPDATE",
        "ts": 1686754357822
      }, {
        "objectId": "OE87DT9330H7R",
        "type": "UPDATE",
        "ts": 1686754358007
      }]
    }
  }
}
const [merchantId, response] = Object.entries(req.body.merchants).pop();

console.log({ merchantId, response });
.as-console-wrapper { top: 0; max-height: 100% !important; }

Safe version with optional chaining and guards:

const [merchantId, response] = Object.entries(req?.body?.merchants ?? {})?.pop() ?? [];
Mr. Polywhirl
  • 42,981
  • 12
  • 84
  • 132
0

As it turns out, there is a way to get the value of a key/value pair without knowing the key and that is by converting it to an array first. Probably not the best but the following was my workaround.

const notify = req.body;
    let merchantId = Object.entries(notify.merchants)[0][0];
    let response = Object.entries(notify.merchants)[0][1]

That sets the merchantId as `"6RDH804A896K1", which is what I was trying to do.

z123
  • 193
  • 1
  • 15