Home > Enterprise >  Convert keys from key value pair to capital case using javaScript
Convert keys from key value pair to capital case using javaScript

Time:10-27

I am trying to convert the keys in JSON to the capital case using Javascript. I am successful to some extent. However, it is not creating the arrays in the correct way. It is inserting numbers before every object inside an array.

Input:

{
  "id": "123",
  "retweetCheck": {
    "result": "OK",
    "checks": [
      {
        "cId": "123"
      },
      {
        "cId": "456"
      }
    ]
  },
  "tweetCheck": {
    "result": "OK",
    "cId": "345",
    "check": "Fail"
  }
}

Code to convert the keys to capital case:

    var responseContent = context.getVariable("response.content") || "";
    responseContent = JSON.parse(responseContent) || "";
    transformedCapitalizedObj = keysToCapitalCase(responseContent);
    var finalResponseObj = {
        Data: transformedCapitalizedObj
    };
    context.setVariable("response.content", JSON.stringify(finalResponseObj));

The function

function objEntries(obj) {
    const keys = Object.keys(obj);
    const keyValuePairs = keys.map(key => {
        const value = obj[key];
        return [key, value];
    });
    return keyValuePairs;
}
function keysToCapitalCase(objToProcess) {
    if (!objToProcess || typeof objToProcess !== "object") return null;
    var finalObj = {};
    objToProcess = objEntries(objToProcess);
    objToProcess.forEach(function (entry) {
        var key = entry[0];
        var value = entry[1];
        key = key.charAt(0).toUpperCase()   key.slice(1);
        if (typeof value == "object" || (value instanceof Array)) {
            value = keysToCapitalCase(value);
        }
        finalObj[key] = value;
    });
    return finalObj;
}

The output I am getting currently is:

{
   "Data":{
      "RetweetCheck":{
         "Checks":{
            "0":{
               "CId":"123"
            },
            "1":{
               "CId":"456"
            }
         },
         "Result":"OK"
      },
      "Id":"123",
      "TweetCheck":{
         "CId":"345",
         "Check":"Fail",
         "Result":"OK"
      }
   }
}

But ideally, the output should look like this:

{
  "Data": {
    "Id": "123",
    "RetweetCheck": {
      "Result": "OK",
      "Checks": [
        {
          "CId": "123"
        },
        {
          "CId": "456"
        }
      ]
    },
    "TweetCheck": {
      "Result": "OK",
      "CId": "345",
      "Check": "Fail"
    }
  }
}

It is basically inserting a serial number before each object inside an array instead of []. How this can be rectified. Any help will really do wonders.

CodePudding user response:

As indicated by the {} brackets, instead of the wanted [] brackets you are creating an empty object and not an Array.
To create an Array just change your var finalObj = {}; to var finalObj = [];
with an Array finalObj[key] = value will no longer work, you will now have to use finalObj.push(value)

CodePudding user response:

When you call your function keysToCapitalCase(), first check if you have an array (with ES6, you can do this using Array.isArray()), and if you do, you can map the objects / inner arrays within that array to the result of recursively calling your keysToCapitalize function. Otherwise, if you get a standard object that isn't an array, you can perform your standard object mapping:

const obj = { "id": "123", "retweetCheck": { "result": "OK", "checks": [{ "cId": "123" }, { "cId": "456" } ] }, "tweetCheck": { "result": "OK", "cId": "345", "check": "Fail" } };

function keysToCapitalCase(objToProcess) {
  if (!objToProcess || typeof objToProcess !== "object") return null;
  
  if(Array.isArray(objToProcess)) {
    return objToProcess.map(obj => keysToCapitalCase(obj));
  }
  
  var finalObj = {};
  objToProcess = Object.entries(objToProcess); // if you can support it, `Object.entries()` does what `objEntries` does
  objToProcess.forEach(function(entry) {
    var key = entry[0];
    var value = entry[1];
    key = key.charAt(0).toUpperCase()   key.slice(1);
    if (typeof value == "object") {
      value = keysToCapitalCase(value);
    }
    finalObj[key] = value;
  });
  return finalObj;
}

var finalResponseObj = {Data: keysToCapitalCase(obj)};
console.log(finalResponseObj);
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

I would probably write the above method in a similar way, but instead using some inbuilt functions to make it a little more concise, such as .map() and Object.fromEntries():

const obj = { "id": "123", "retweetCheck": { "result": "OK", "checks": [{ "cId": "123" }, { "cId": "456" } ] }, "tweetCheck": { "result": "OK", "cId": "345", "check": "Fail" } };

const cap = str => str.charAt(0).toUpperCase()   str.slice(1);
const keysToCapitalCase = (objToProcess) => {
  if (Object(objToProcess) !== objToProcess) return null;

  return Array.isArray(objToProcess) 
    ? objToProcess.map(obj => keysToCapitalCase(obj))
    : Object.fromEntries(Object.entries(objToProcess).map(([key, val]) => [
      cap(key), Object(val) === val ? keysToCapitalCase(val) : val
    ]));
}

const finalResponseObj = {Data: keysToCapitalCase(obj)};
console.log(finalResponseObj);
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

  • Related