Home > OS >  Javascript How to update all Property Names in nested object
Javascript How to update all Property Names in nested object

Time:04-08

I would like to return a new object with the updated property names in the nested object.

For example in the fakeData below, I would like to update all the property names from:

id = Id
title =  PhaseTitle
subTasks = Phases
dependencyTest = Dependency
fromId = FromId
toId = ToId

The data that I am trying to update :

let fakeData = [
      {
        id: 7,
        title: 'Software validation, research and implementation',
        dependencyTest: null,
        subtasks: [
          {
            id: 18,
            title: 'Project Kickoff',
            dependencyTest: [
              {
                id: 100,
                fromId: 18,
                toId: 11,
              },
              {
                id: 101,
                fromId: 18,
                toId: 19,
              }
            ]
          },
          {
            id: 11,
            title: 'Research',
            dependencyTest: null,
            subtasks: [
              {
                id: 19,
                title: 'Validation with Customers',
                dependencyTest: [
                  {
                    id: 200,
                    fromId: 19,
                    toId: 18,
                  },
                  {
                    id: 330,
                    fromId: 19,
                    toId: 12,
                  }
                ]
              }
            ]
          },
          {
            id: 12,
            title: 'Design',
            dependencyTest: null,
            subtasks: [
              {
                id: 22,
                title: 'UI Design',
                dependencyTest: [{
                  id: 135,
                  fromId: 18,
                  toId: 19,
                }]
              }
            ]
          }
        ]
      }
    ];

So far I've tried to use the recurrsion to do this but the subtask are not updating correctly

  private test() : void {
    const updatedObject = [];
    const recursiveFn = (obj : any ) : void => {
      for (let i = 0; i < obj.length; i  ) {
        const entity: any = {
          Id: obj[i].id,
          Duration: obj[i].duration,
          PhaseName: obj[i].title,
          Phases: obj[i].subtasks,
          Dependency: null
        };

        const dependency : any = [];

        if (obj[i].dependency && obj[i].dependency.length > 0) {
          for (const depend of obj[i].dependency) {
            dependency.push({
              Id: depend.id.toString(),
              FromId: depend.fromId.toString(),
              ToId: depend.toId.toString(),
              Type: depend.type
            });
          }
        }
        entity.Dependency = dependency;

        // This doesn't work
        updatedObject.push(entity);

        if (obj[i]?.subtasks?.length > 0) {
          recursiveFn(obj[i].subtasks);
        }
      }
    };

    recursiveFn(this.fakeData);
  }

CodePudding user response:

This is a short solution it return a new array without changing the existing one.

It use recursion and uses the Object.entries and fromEntries functions that do exactly that are perfect for this use case

const mapping = {
  id: 'Id',
  title: 'PhaseTitle',
  subtasks: 'Phases',
  dependencyTest: 'Dependency',
  fromId: 'FromId',
  toId: 'ToId'
}


const rename = (data) => data.map(d => 
  Object.fromEntries(Object.entries(d).map(([k, v]) => {
    return [mapping[k] || k, Array.isArray(v)? rename(v):v]
  })))


let fakeData = [{
  id: 7,
  title: 'Software validation, research and implementation',
  dependencyTest: null,
  subtasks: [{
      id: 18,
      title: 'Project Kickoff',
      dependencyTest: [{
          id: 100,
          fromId: 18,
          toId: 11,
        },
        {
          id: 101,
          fromId: 18,
          toId: 19,
        }
      ]
    },
    {
      id: 11,
      title: 'Research',
      dependencyTest: null,
      subtasks: [{
        id: 19,
        title: 'Validation with Customers',
        dependencyTest: [{
            id: 200,
            fromId: 19,
            toId: 18,
          },
          {
            id: 330,
            fromId: 19,
            toId: 12,
          }
        ]
      }]
    },
    {
      id: 12,
      title: 'Design',
      dependencyTest: null,
      subtasks: [{
        id: 22,
        title: 'UI Design',
        dependencyTest: [{
          id: 135,
          fromId: 18,
          toId: 19,
        }]
      }]
    }
  ]
}];





console.log(rename(fakeData))

CodePudding user response:

I proposed the translateObject(o) function that will take the o object as an argument and it will translate its properties, and recursively the properties of the object in subtasks (if any), according to the map defined in translations.

The call is made at the end looping through each element of the main array fakeData. The fakeData array in the end will contain all its objects (and the nested objects in subtasks) translated.

let fakeData = [
      {
        id: 7,
        title: 'Software validation, research and implementation',
        dependencyTest: null,
        subtasks: [
          {
            id: 18,
            title: 'Project Kickoff',
            dependencyTest: [
              {
                id: 100,
                fromId: 18,
                toId: 11,
              },
              {
                id: 101,
                fromId: 18,
                toId: 19,
              }
            ]
          },
          {
            id: 11,
            title: 'Research',
            dependencyTest: null,
            subtasks: [
              {
                id: 19,
                title: 'Validation with Customers',
                dependencyTest: [
                  {
                    id: 200,
                    fromId: 19,
                    toId: 18,
                  },
                  {
                    id: 330,
                    fromId: 19,
                    toId: 12,
                  }
                ]
              }
            ]
          },
          {
            id: 12,
            title: 'Design',
            dependencyTest: null,
            subtasks: [
              {
                id: 22,
                title: 'UI Design',
                dependencyTest: [{
                  id: 135,
                  fromId: 18,
                  toId: 19,
                }]
              }
            ]
          }
        ]
      }
    ];

//---------------------------------------------------------------

let translations = {
  "id" : "Id",
  "title" : "PhaseTitle",
  "subtasks" : "Phases",
  "dependencyTest" : "Dependency",
  "fromId" : "FromId",
  "toId" : "ToId"
 };
 
 function translateObject(o){
 
    if ( o.hasOwnProperty('subtasks') && o.subtasks !== null ){
      o.subtasks.forEach( (child) => translateObject(child) )
    }

    if ( o.hasOwnProperty('dependencyTest') && o.dependencyTest !== null){
      o.dependencyTest.forEach( (child) => translateObject(child) )
    }
 
    Object.keys(translations).forEach((propertyName, i)=>{
        let translatedPropertyName = translations[propertyName];
        if( o.hasOwnProperty(propertyName) ){
           o[translatedPropertyName] = o[propertyName];
           delete o[propertyName]
        }           
    });
    
 }

fakeData.forEach((o)=>{
  translateObject(o);
})

console.log(fakeData);

CodePudding user response:

Simply supply a list of what keys you want to rename and it'll recursively look through your object and update their names.

I might add that this function accepts both arrays and objects. It also mutates the original object so reduces memory usage.

let fakeData = [ { id: 7, title: 'Software validation, research and implementation', dependencyTest: null, subtasks: [ { id: 18, title: 'Project Kickoff', dependencyTest: [ { id: 100, fromId: 18, toId: 11, }, { id: 101, fromId: 18, toId: 19, } ] }, { id: 11, title: 'Research', dependencyTest: null, subtasks: [ { id: 19, title: 'Validation with Customers', dependencyTest: [ { id: 200, fromId: 19, toId: 18, }, { id: 330, fromId: 19, toId: 12, } ] } ] }, { id: 12, title: 'Design', dependencyTest: null, subtasks: [ { id: 22, title: 'UI Design', dependencyTest: [{ id: 135, fromId: 18, toId: 19, }] } ] } ] } ];     
   
let updateList = new Map([ ["id", "Id"], ["title", "PhaseTitle"], ["subtasks", "Phases"], ["dependencyTest", "Dependency"], [ "fromId", "FromId" ], ["toId", "ToId"]]);

let recursive = (obj) => {

  if(Array.isArray(obj)) obj.forEach(o => recursive(o));

  Object.keys(obj).forEach(k => {
    if(Array.isArray(obj[k])) obj[k].forEach(o => recursive(o));
    if(updateList.has(k)) {
      obj[updateList.get(k)] = obj[k];
      delete obj[k];
    }  
  })
}

recursive(fakeData)

console.log(fakeData);

  • Related