Skip to content
Advertisement

Create new Js Array of Object with new key name from old objects

I am trying to create a new Array of Object from the data which is another array of objects coming from API. The new Array which we will get in the end should get value from dataFromApi and updated key names to will be selected from another array that holds the previous key and new key name | label for those properties. This data will be exported in CSV file. So we are using reusable components for this export, I want to make this conversion of data dynamic. As the current key name looks like currentApplyStart and in the CSV file they are not good headers.

So,

We are getting a new key names array from this function. What this function is trying to solve is, get the pair of oldKeyName and its newKeyName || new key and label

const newKeyName = () =>  { 
if (data?.length) {
            const allColumn = Object.keys(data?.[0]);
            const columnKeys = dataColumns
                .filter((header) => allColumn.indexOf(header.key) >= 0)
                .map((column) => {
                    return { key: column.key, label: column.label };
                });
            return columnKeys;
        };
}

which return something like this. This is demo data.

let dataColumns = [
{key : 'color', label : 'newColor'} , 
{key : 'annoying', label : 'newAnnoying'},
key : 'height', label : 'newHeight'}
//  we only return these top three as the api data object consist only has these two keys in itself.
{key : 'meta', label : 'newMeta'}
{key : 'costApplyStart', label : 'CPA'}
]

let newKeyNames = [
{key : 'color', label : 'newColor'} , 
{key : 'annoying', label : 'newAnnoying'},
{key : 'height', label : 'newHeight'} ] 
// as only these three key name exist in dataFromApi.

So let’s say we have an array of the object which comes from API

let DataFromApi = [
{ 
  color: 'red',
  annoying: true,
  height: 'unknown',
},
{ 
  color: 'blue',
  annoying: false,
  height: 'unknown',
},
{ 
  color: 'red',
  annoying: false,
  height: 'unknown',
},
];

The data which i want it in the end should be like this

let finalData = [
{newColor: 'red',newAnnoying: true, newHeight: 'unknown',}, 
{newColor: 'blue',newAnnoying: false, newHeight: 'unknown',}
{
  color: 'red',
  annoying: 'false,
  newHeight: 'unknown',
},
]

Observe is data, that I changed the old key name into a new key which I want to be header in csvFile. I can not mutate the original data , for that reason i have to create a new data array . The solution i tried was this but I was not getting the desired result.

  newKeyNames?.map((field) => {
                return dataFromAPi.map((item) => {
                    if (item.hasOwnProperty(field.key)) {
                        item[field.label] = item[field.key];
                    }
                });
            });

Advertisement

Answer

Based on the later explanation, I’ve updated the answer.

Here’s the JSFiddle link: https://jsfiddle.net/_ghost/py8et9vf/57/

let DataFromApi = [
  { 
    color: 'red',
    annoying: true,
    height: 'unknown',
    meta: { one: '1', two: '2'}
  },
  { 
    color: 'blue',
    annoying: false,
    height: 'unknown',
    meta: { one: '1', two: '2'}
  },
  { 
    color: 'red',
    annoying: true,
    height: 'unknown',
    meta: { one: '1', two: '2'}
  },
];

let dataColumns = [
  {key : 'color', label : 'newColor'} , 
  {key : 'annoying', label : 'newAnnoying'},
  {key : 'somekey', label : 'newSomeKey'},
  {key : 'anotherKey', label : 'newAnotherKey'}
]

function getAllDataCols(){
    let obj = {};
  
  // Make a new object from all the dataColums for ease of use
  
  dataColumns.forEach(item => {
    obj[item.key] = item.label
  })
  
  return obj
}

function processDataFromApi(newDataCols){

    let result = []

    DataFromApi.forEach(obj => {
  
    let newObj = {}
  
    Object.keys(obj).forEach(name => {
            
        if(newDataCols[name] !== undefined){
            //if we have an alternative for the name
          
          newObj[newDataCols[name]] = obj[name]
        }else{
            // we don't have an alternative. use the already existing name
            newObj[name] = obj[name]
        }
      
    })
    
    result.push(newObj)
  })
    
  return result
}

let newDataCols = getAllDataCols()

let response = processDataFromApi(newDataCols)

console.log(response)
User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement