3

I have an object with nested objects with the below structure, how can I dynamically add new items (newData) to the cost3 array?

I have tried that but the new data isn't being pushed, what am I doing wrong?

const [file, setFile] = useState({})

setFile(file=> ({
      ...file,
      [cost3]: {
          ...file.cost3,
          newData
      }
}))

File object:

{
      "info": {

      },
      "client": {

      },
      "costs": {
        "cost1": 1,
        "cost2": 5,
        "cost3": [
          {
            "a": "test",
            "b": "test",
            "c": "test",
          },
          {
            "d": "test",
            "e": "test",
            "f": "test",
          },
         //etc..       
        ],
        "cost4": [
          {
            "l": "test",
            "n": "test",
            "m": "test",
          },
        //etc..
        ]
      }
    }
VLAZ
  • 26,331
  • 9
  • 49
  • 67
user3378165
  • 6,546
  • 17
  • 62
  • 101
  • What is `[const3]` in setFile, I don't see you define the const3 variable anywhere. – HMR Oct 11 '19 at 07:00

4 Answers4

2

const file = {
  "info": {

  },
  "client": {

  },
  "costs": {
    "cost1": 1,
    "cost2": 5,
    "cost3": [{
        "a": "test",
        "b": "test",
        "c": "test",
      },
      {
        "d": "test",
        "e": "test",
        "f": "test",
      },
      //etc..       
    ],
    "cost4": [{
        "l": "test",
        "n": "test",
        "m": "test",
      },
      //etc..
    ]
  }
}

const newData = { x: 'I am new' }

console.log(
  {
    ...file,
    costs: {
      ...file.costs,
      cost3: [
        ...file.costs.cost3,
        newData
      ]
    }
  }
)
giuseppedeponte
  • 2,366
  • 1
  • 9
  • 19
  • 1
    If you see how state is initialezed `useState({})` you can conclude that `...file.costs.cost3,` will throw a "const3 of undefined" error. I would suggest using some sort of [get](https://stackoverflow.com/a/58335595/1641941) to make it less error prone. – HMR Oct 11 '19 at 07:25
2

Your code is incorrect.

Replace [cost3] with cost3 and {} with [], like so:

setFile(file=> ({
      ...file,
      costs: {
        ...file.costs,
        cost3: [
          ...file.costs.cost3,
          newData
        ]
      }
}))
UtkarshPramodGupta
  • 7,486
  • 7
  • 30
  • 54
  • Looks like OP is trying to set `file.const.const3` but since file is initialized with `{}` trying to spread file.const.const3 will throw because const is initially undefined. Maybe better to use some sort of [get](https://stackoverflow.com/a/58335595/1641941) – HMR Oct 11 '19 at 07:13
0

You can try it using concat.

cost3 = [];
const [file, setFile] = useState({});

setFile(file => ({
  cost3: file.cost3.concat(newData),
}));
HMR
  • 37,593
  • 24
  • 91
  • 160
Pushprajsinh Chudasama
  • 7,772
  • 4
  • 20
  • 43
  • I would suggest using concat instead of push because push will mutate the array. – HMR Oct 11 '19 at 07:08
-1

You can use .push() method to add item to object, for dynamic addition you can iterate through the array.

Atul Joshi
  • 15
  • 2