Search code examples
javascriptvue.jsvuejs2logic

Merging nested array using map in JS


I am fetching a data from Laravel API this way

 $inventory = Gifts::with('allocation')->get();
 $response = [
   'data' => $inventory->toArray(),
 ]

The output for the above looks like the image below in the console

enter image description here

This is what is inside the 0: {…}

{
    "id": 1,
    "name": "Bar 1",
    "allocation": [
        {
            "id": 1,
            "location_id": "1",
            "qty": "2",
        },
        {
            "id": 2,
            "location_id": "4",
            "qty": "32",
        },
        {
            "id": 3,
            "location_id": "7",
            "qty": "12",
        }
    ]
}

I'm trying to get an output like this

{
    "isEditable": false,
    "id": 1,
    "name": "Bar 1",
    "location1": "2"
    "location4": "32"
    "location7": "12"
}

It's an array that consists of 100+ entries like this and the allocation can be more or less or maybe empty as well

What I have done so far

 const array = result.data(gift => ({ isEditable: false, ...gift }));

This adds "isEditable" field to the array.


Solution

  • You could use Array.prototype.map() to map the result array into a new one that only includes id, name, and the locationNN properties.

    In the Array.prototype.map()'s callback:

    1. Use the spread operator to separate the allocation property from the other properties of each array item (call it otherProps e.g.):

    2. Spread the otherProps into a new object, inserting the isEditable property.

    3. Map the allocation items into a key-value pair array, where the key is location_id appended to "location"; and the value is the qty property.

    4. Use Object.fromEntries() on the key-value pair array to create an object, and spread that object into the outer object to be returned.

    const output = result.map(r => {
      const { allocation, ...otherProps } = r 1️⃣
      return {
        ...otherProps, 2️⃣
        isEditable: false,
        ...Object.fromEntries( 4️⃣
          allocation.map(a => [`location${a.location_id}`, a.qty]) 3️⃣
        )
      }
    })
    

    demo