Home > Enterprise >  JavaScript Merging Objects into New Array from API
JavaScript Merging Objects into New Array from API

Time:08-29

So I'm pulling two arrays from an API for a Vue.JS DataTable, one of the arrays contains and object with information for the table about a specific devices, such as names, IDs, dates, and etc., whereas the other array contains an object with multiple statuses, such as "lost", "noSignal", and etc.

I need to have these arrays merged and inputted into a new object, which will then be stored into a new Array for the DataTable:

let data = {
 name: name,
 IDs: id,
 date: date
 warning: null,
 error: null
}

The array with statuses, array 2, dictate the values of "warning" and "error", and I need to loop through and input each "data" object into a new array with each individual warning or error, so if "lowSignal" AND "lost" are both true, then the data table will have two entries, one where the warning column is populated with "lowSignal" and the error column has nothing, and another where the error column is populated with "lost" and warning has nothing in it.

Here is what I've tried: Having multiple if conditions for each possible error, such as if(lowSignal), if(lost), and etc., with each if statement containing a new variable set to represent the data object, let temp = data;, then I would configure and merge: temp.warning = lowSignal, merge.push[temp] This did not work, as if both lowSignal AND lost were true, it would input two entries into the DataTable (which is correct), but both entries would have warning and error populated with the same thing (incorrect). I've also attempted to have a .forEach loop, as well as an object length loop, both returning the same result.

Any suggestions? Thanks

CodePudding user response:

You can use the Spread Operator to merge two objects. If you have a property in one array related to a property in the other array (device.id and status.deviceId), you can do something similar to this:

const devices = [
    {
        id: 1,
        name: 'Device A',
    },
    {
        id: 2,
        name: 'Device B',
    },
    {
        id: 3,
        name: 'Device C',
    },
    {
        id: 4,
        name: 'Device D',
    },
]

const statuses = [
    {
        id: 1,
        deviceId: 1,
        warning: 'low signal',
        error: 'lost'
    },
    {
        id: 2,
        deviceId: 2,
        warning: 'low signal',
        error: null
    },
    {
        id: 2,
        deviceId: 3,
        warning: null,
        error: 'lost'
    },
    {
        id: 2,
        deviceId: 3,
        warning: null,
        error: null
    }
]

const devicesWithStatus = devices.reduce((acc, device) => {
    // Find the status where deviceId equals to the ID of the device
    const status = statuses.find((status) => status.deviceId === device.id)
    
    // If there's a warning, merge the device and the warning
    if(status?.warning)
      acc.push({
        ...device,
        warning: status.warning
      })

    // If there's an error, merge the device and the error
    if(status?.error)
      acc.push({
        ...device,
        error: status.error
      })
     
    // If there's no error or warning, just push the device
    if(!status?.error && !status?.warning)
      acc.push(device)

    return acc
}, [])

console.log(devicesWithStatus)

CodePudding user response:

If I understood you correctly try like following snippet:

const arr = [{id: 0, name: 'a'}, {id: 1, name: 'b'}, {id: 2, name: 'c'}, {id: 3, name: 'd'}]
const stat = [{id: 0, lost: true, lowSignal: true}, {id: 1, lost: false, lowSignal: true}, {id: 2, lost: true, lowSignal: false}]

const res = []
arr.forEach(a => {
  let st = stat.find(s => s.id === a.id)
  a.error = null
  a.warning = null
  if(st) {
    if(st.lost) {
      res.push({ ...a, error: 'lost' })
    } 
    if (st.lowSignal) {
      res.push({ ...a, warning: 'lowSignal' })
    }
  } else {
    res.push({ ...a })
  }
})

console.log(res)

  • Related