Home > Net >  How to add a property to every object in a nested JSON structure in JavaScript?
How to add a property to every object in a nested JSON structure in JavaScript?

Time:05-18

Let's suppose I have an API response that looks like this:

const data = {
  users: [
    { name: "John", teams: [{ name: "Liverpool" }] },
    { name: "Sam", teams: [{ name: "MC" }, { name: "United" }] },
  ],
  photos: [
    { id: "123", types: ["JPG", "PNG"], comments: [{ description: "sample photo" }] },
  ],
};

I want to transform it by adding the rid property to each object.

const data = {
  rid: "ABC",
  users: [
    { rid: "ABC", name: "John", teams: [{ rid: "ABC", name: "Liverpool" }] },
    { rid: "ABC", name: "Sam", teams: [{ rid: "ABC", name: "MC" }, { rid: "ABC", name: "United" }] },
  ],
  photos: [
    { rid: "ABC", id: "123", types: ["JPG", "PNG"], comments: [{ rid: "ABC", description: "sample photo" }] },
  ],
};

How can I do so? I think there is some kind of recursion involved but I haven't been able to draft a solution?

Thanks.

CodePudding user response:

You just need to iterate through object with recursive function.

Try below snippet.

const data = {
  users: [
    { name: 'John', teams: [{ name: 'Liverpool' }] },
    { name: 'Sam', teams: [{ name: 'MC' }, { name: 'United' }] },
  ],
  photos: [
    { id: '123', types: ['JPG', 'PNG'], comments: [{ description: 'sample photo' }] },
    { key: null }, // Fixed null values
  ],
}

function addProperty(obj, key, val) {
  if (!obj || typeof obj !== 'object') return
  if (!Array.isArray(obj)) obj[key] = val
  Object.values(obj).forEach((obj) => addProperty(obj, key, val))
}

addProperty(data, 'rid', 'ABC')

console.log(data)

CodePudding user response:

Firstly the OP is not going to alter a JSON object. JSON is a string based standardized data interchange format and a JavaScript namespace with static methods.

But the OP is going to recursively traverse/walk a JSON-conform object-type.

Thus the implementation of such a function needs to take into account just object-types and arrays.

In case of an array-type the recursive call takes place forEach array-item. In case of an object-type all values of the object's own enumerable keys/properties will be processed recursively.

For any object-type in addition the assignment of a provided custom object (one or more entries) takes place.

The beneath provided function provides as feature the possibility to define the minimum object-level from where an assignement is going to be applied.

function recursivelyAssignDataToEveryObjectType(type, data, startLevel = 0, level = 0) {
  if (Array.isArray(type)) {
    type
      .forEach(item =>
        recursivelyAssignDataToEveryObjectType(item, data, startLevel, level   1)
      );
  } else if (type && 'object' === typeof type) {
    Object
      .values(type)
      .forEach(value =>
        recursivelyAssignDataToEveryObjectType(value, data, startLevel, level   1)
      );
    if (level >= startLevel) {
      Object.assign(type, data);
    }
  }
}

const data = {
  users: [
    { name: "John", teams: [{ name: "Liverpool" }] },
    { name: "Sam", teams: [{ name: "MC" }, { name: "United" }] },
  ],
  photos: [
    { id: "123", types: ["JPG", "PNG"], comments: [{ description: "sample photo" }] },
  ],
};
recursivelyAssignDataToEveryObjectType(data, { rid: "ABC" }, 2);

console.log({ data });
.as-console-wrapper { min-height: 100%!important; top: 0; }

  • Related