[Vuejs]-Object nested reduce or map into one object

0๐Ÿ‘

I made a tweak and copied the block of code and it does now work, but I am looking for a better cleaner way to do this:

async getBatches() {
      try {
        let res = await farmStockService.getAllBatches();

        

        const result = res.data.data.map((element) => {
          const keysWithNameProp = Object.keys(element).filter(key => element[key].name !== undefined);
          const copyOfElement = {...element};
          keysWithNameProp.forEach(prop => {
            copyOfElement[prop] = element[prop].name;
          })
          return copyOfElement;
        });

        const newresult = result.map((element) => {
          const keysWithNameProp = Object.keys(element).filter(key => element[key].species !== undefined);
          const copyOfElement = {...element};
          keysWithNameProp.forEach(prop => {
            copyOfElement[prop] = element[prop].species;
          })
          return copyOfElement;
        });

       

        this.batches = newresult;

      } catch (e) {
        console.error(e);
      }
    },

enter image description here

0๐Ÿ‘

You may use ... spread operator.

If the key is not dynamic, you can use solution1 below.

const response = { data: [ { name: "Batch1", description: "seed", age: 2, quantity: 1000, source: "Hatchery", hatchery: "robs hatchery", location: "dingle", shellfish: { species: "oyster", }, grade_list: { name: "Grade0", }, stock_type: { name: "seeds", }, }, { name: "Batch2", description: "Batch2", age: 20, quantity: 15700, source: "aka", hatchery: "aka", location: "dingle", shellfish: { species: "oyster", }, grade_list: { name: "Grade1", }, stock_type: { name: "mature", }, }, { name: "5555", description: "45", age: 1, quantity: 134, source: "fhh", hatchery: "hfhj", location: "garden", shellfish: { species: "oyster", }, grade_list: { name: "Grade0", }, stock_type: { name: "seeds", }, }, ], };

const result1 = response.data.map(item => ({
  ...item,
  shellfish: item.shellfish.species,
  grade_list: item.grade_list.name,
  stock_type: item.stock_type.name,
}));

console.log({result1});

If the key is dynamic, you can use solution2 below.

const response = { data: [ { name: "Batch1", description: "seed", age: 2, quantity: 1000, source: "Hatchery", hatchery: "robs hatchery", location: "dingle", shellfish: { species: "oyster", }, grade_list: { name: "Grade0", }, stock_type: { name: "seeds", }, }, { name: "Batch2", description: "Batch2", age: 20, quantity: 15700, source: "aka", hatchery: "aka", location: "dingle", shellfish: { species: "oyster", }, grade_list: { name: "Grade1", }, stock_type: { name: "mature", }, }, { name: "5555", description: "45", age: 1, quantity: 134, source: "fhh", hatchery: "hfhj", location: "garden", shellfish: { species: "oyster", }, grade_list: { name: "Grade0", }, stock_type: { name: "seeds", }, }, ], };

function isObject(obj) {
  return typeof obj === "object" && obj !== null && !Array.isArray(obj);
}

const result2 = response.data.map(item => {
  const keys = Object.keys(item);

  let flattenObj = {};
  for (const key of keys) {
    const value = item[key];
    if (isObject(value)) {
      flattenObj = { ...flattenObj, [key]: value[Object.keys(value)[0]] };
    }
  }
  return { ...item, ...flattenObj };
});

console.log(result2);

0๐Ÿ‘

You can define a helper function resolveNestedProps() which accepts an object and an array of properties to look for. If any of them are found it returns the value, otherwise it returns the obj. Note that this will return the first property that matches, so if any of your objects have a name and species whichever is matched first will be returned.

Here iterating over the Object.entries() of each element and returning a new object using Object.fromEntries()

const res = { data: { data: [ { name: 'Batch1', description: 'seed', age: 2, quantity: 1000, source: 'Hatchery', hatchery: { name: 'robs hatchery' }, location: { name: 'dingle' }, shellfish: { species: 'pacific gigas' }, stock_type: 'seeds', }, { name: 'Batch2', description: 'Batch2', age: 20, quantity: 15700, source: 'aka', hatchery: { name: 'aka' }, location: { name: 'dingle' }, shellfish: { species: 'pacific gigas' }, stock_type: 'mature', }, { name: '5555', description: '45', age: 1, quantity: 134, source: 'fhh', hatchery: { name: 'hfhj' }, location: { name: 'garden' }, shellfish: { species: 'pacific gigas' }, stock_type: 'seeds', }, ], }, };

const resolveNestedProps = (obj, props) => {
  for (const key of props) {
    if (obj[key] !== undefined) {
      return obj[key];
    }
  }

  return obj;
};

const nestedProps = ['name', 'species']; // define properties to look for
const result = res.data.data.map((element) =>
  Object.fromEntries(
    Object.entries(element).map(([k, v]) => {
      if (typeof v === 'object' && v !== null && !Array.isArray(v)) {
        v = resolveNestedProps(v, nestedProps);
      }

      return [k, v];
    })
  )
);

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

Leave a comment