Search code examples
javascriptjsonrxjscasting

What can be the optimized or efficient way to transform/modify the received JSON input response keys in JavaScript/Typescript


I have the solution for the problem but I am posting this question in community in search of a Lightweight or say efficient way to do this if possible. Thus a better approach/advise is appreciated.

I have a dictionary / key Value pair data which looks like below basically its the mapping that will be used for transformation of the response.


    KEYS  :  VALUE
 

    "score": "RelevantScore",
    "headline": "Headline",
    "subtitle1": "PublishedDate",
    "subtitle2": "Stage",
    "body": "Summary",
    "labels": "Tag"


My aim is to transform the JSON Input response, I need to replace the old properties (VALUE) with its mapped KEY from the mapping data above. let take a example below

I have a JSON object with the following content: (ASSUME INPUT RESPONSE RECIVED)

"Data": [{
            "RowId": 1,
            "Headline": "some data",
            "PublishedDate": "2022-09-29",
            "Summary": " some data",
            "SourceURL": "https://www.google.com",
            "RelevantScore": 0,
            "Stage": null,
            "Tag": "",          
}]

I want to change the "RelevantScore" key to "score" so it would become (EXPECTED OUTPUT AFTER SWAPPING)

"Data": [{
            "RowId": 1,
            "headline": "some random headline",
            "subtitle1": "2022-09-29",
            "body": "some data",
            "SourceURL": "https://www.google.com",
            "score": 0,
            "subtitle2": null,
            "labels": "",
}]

Note :- We will be using the mapping table above to swap the keys

The Input JSON response properties name will be replaced/Swapped by the respective mapping key so that a new response can be crafted from the old one. non matching keys can be ignored

Simple Example :- RelevantScore key from response is being replaced by its mapped value Score to form a new response object.

EXISTING FUNCTION I HAVE:-

function renameKey ( obj, oldKey, newKey ) {
  obj[newKey] = obj[oldKey];
  delete obj[oldKey];
}

EXISTING APPROACH:-

const json = `
  [
    {
      "RelevantScore":"5078c3a803ff4197dc81fbfb"
    }
  ]
`;
const arr = JSON.parse(json);
arr.forEach( obj => renameKey( obj, 'RelevantScore', 'Score' ) ); // Call to the method
const updatedJson = JSON.stringify( arr );

**RESULT **:-

const json = `
  [
    {
      "Score":"5078c3a803ff4197dc81fbfb"
    }
  ]
`;

Solution

  • transformResposne(dynamicData :any[]): any [] {
    
          dynamicData.forEach( obj => renameKeys( obj, new Map(Object.entries(this.controls))));
          function renameKeys( obj, columnMap : Map<string, string> ) {
            columnMap.forEach(function(oldkey, newKey) {
              if (oldkey in obj)
              {
                obj[newKey] = obj[oldkey];
                delete obj[oldkey];
              }
            })
          }
          return dynamicData;
       
      };
    

    DATA RESPRESENTATION :-

    dynamicData = [{
               "RelevantScore": 0                
         }]
    
       controls = {
        "score": "RelevantScore",
       }
    

    OUTPUT :-

     dynamicData = [{
                   "score": 0                
             }]