2

I am creating an object with values from an api response. Is there a neater way to do this?

My code:

const variables = {
    name: result.data.data.table.name,
    org: the_org,
    val1: result.data.data.table.val1,
    val2: result.data.data.table.val2,
    val3: result.data.data.table.val3,
    val4: result.data.data.table.val4,
    val5: result.data.data.table.val5,
    val6: result.data.data.table.val6,
    val7: new_vals7,
  };

Some values come from an api call and some are not. Was just wondering is there is a neater way to do this?

6
  • keep name,val1,...val6 in array and loop it and add to object. val7 and org you will have to manually const obj = ["name","val1",..."val6"].reduce((acc,curr)...,{{org:the_org,val7:new_val7}})
    – cmgchess
    Commented May 15, 2023 at 13:46
  • Are those the only properties of result.data.data.table or are there more?
    – Andy
    Commented May 15, 2023 at 13:58
  • @Andy there are more
    – nb_nb_nb
    Commented May 15, 2023 at 13:59
  • 1
    @nb_nb_nb this was what i meant const variables = ['name', 'val1','val2', 'val3', 'val4', 'val5', 'val6'].reduce((acc,curr) => ({...acc,[curr]:result.data.data.table[curr]}),{org:the_org,val7:new_vals7})
    – cmgchess
    Commented May 15, 2023 at 14:05
  • 1
    You could spread result.data.data.table into the new object.
    – Reyno
    Commented May 15, 2023 at 14:05

3 Answers 3

2

You can use the spread operator to include extra entries from another object. Object.fromEntries produces that object by mapping from the numbers 1 through 6 to properties of the table object from the result.

const result = {
  data: {
    data: {
      table: {
        name: 'name',
        val1: 'val1',
        val2: 'val2',
        val3: 'val3',
        val4: 'val4',
        val5: 'val5',
        val6: 'val6'
      }
    }
  }
}

const the_org = 'the_org'
const new_vals7 = 'new_vals7'

const table = result.data.data.table;
const variables = {
    name: table.name,
    org: the_org,
    ...Object.fromEntries(Array.from({length: 6}, (_,i)=>`val${i+1}`)
      .map(p=>[p, table[p]])),
    val7: new_vals7,
};

console.log(variables);

2
  • caught TypeError: Iterator value val1 is not an entry object Commented May 15, 2023 at 14:39
  • @silentmantra ah, thanks, there was a bracket in the wrong place. works now Commented May 15, 2023 at 21:23
1

you can try using reduce by keeping a list of the fields you want to extract. for the accumulator you can pass an object with the rest of the properties

const the_org = 'the_org'  
const new_vals7 = 'new_vals7'
const result = {
  data: {
    data: {
      table: {
        name: 'name',
        val1: 'val1',
        val2: 'val2',
        val3: 'val3',
        val4: 'val4',
        val5: 'val5',
        val6: 'val6'
      }
    }
  }
}

const variables = ['name', 'val1','val2', 'val3', 'val4', 'val5', 'val6']
.reduce((acc,curr) => ({...acc,[curr]:result.data.data.table[curr]}),{org:the_org,val7:new_vals7})

console.log(variables)

as Andy mentioned in the comment creating a new object in each iteration can be inefficient. you can avoid that by removing spread syntax.

const the_org = 'the_org'  
const new_vals7 = 'new_vals7'
const result = {
  data: {
    data: {
      table: {
        name: 'name',
        val1: 'val1',
        val2: 'val2',
        val3: 'val3',
        val4: 'val4',
        val5: 'val5',
        val6: 'val6'
      }
    }
  }
}

const variables = ['name', 'val1','val2', 'val3', 'val4', 'val5', 'val6']
.reduce((acc, curr) => {
  acc[curr] = result.data.data.table[curr]
  return acc
}, { org: the_org, val7: new_vals7 })

console.log(variables)

2
  • It's not particularly efficient to create a brand new object on each iteration.
    – Andy
    Commented May 15, 2023 at 14:22
  • 1
    @Andy thank you. i was trying to do a one liner
    – cmgchess
    Commented May 15, 2023 at 15:09
1

If you need all data from the response and overwrite some values in it this could look nice:

const variables = {...result.data.data.table, org: the_org, val7: new_vals7};

If you need only specific values:

    const result={
      data:{
        data:{
          table:{
            name:'name', 
            ...Object.fromEntries([...new Array(6)].map((_,idx)=>'val' + (idx + 1)).map(v => [v, v]))
          }
        }
      }
    };

    // this you need
    const variables = {
        ...Object.fromEntries(
            Object.entries(result.data.data.table)
                .filter(([key]) => /^(val[1-6]|name)$/.test(key))), 
        org: 'the_org', 
        val7: 'new_vals7'
    };

    console.log(variables);

0

Not the answer you're looking for? Browse other questions tagged or ask your own question.