0

I am working with GPS related program so I am actively receiving many location objects. This is the array form I would want to achieve. Initially it should be an empty array and then start with only one child, all incoming location objects would be stored in that one child until some other command is issued. When next event starts, all incoming objects would be stored in second child array, hope you get the gists.

rootArray = [
  [
    {lat: '', long: ''},
    {lat: '', long: ''},
    {lat: '', long: ''},
  ],
  [
    {lat: '', long: ''},
    {lat: '', long: ''},
    {lat: '', long: ''},
  ]
]

This is what I have tried but did not succeed.

// I am working with redux here actually
// rootArray: []

case NEW_LOCATION_OBJECT_COMING:
  return {
    ...state,
    rootArray: state.rootArray[state.rootArray.length].concat(action.payload.locationObject),
  }

2
  • can't you just change concat to push? state.rootArray[state.rootArray.length].push(action.payload.locationObject) Commented Jul 22, 2017 at 16:41
  • Do not use push that will mutate the array, concat on the other hand is a good method that returns a new array.
    – G4bri3l
    Commented Jul 22, 2017 at 16:44

1 Answer 1

2

The items in the array are indexed from 0 to length - 1, so if you try to access the element at index length you will get undefined. We should do this:

...
rootArray: [
  ...state.rootArray.slice(0, state.rootArray.length - 1),
  state.rootArray[state.rootArray.length - 1].concat(action.payload.locationObject)
],
...

The reason is that with the previous approach we were assigning to the rootArray the result of concatenating its last element with the payload, so everything else would get lost and our rootArray would become just a simple array of objects.

We need to preserve what we have by extending the existing array, to achieve this I create a new array that looks like the old rootArray without the last element, the new last element is then the concatenation of the old last element and the payload. I hope it makes sense.

EDIT Given your comment it depends on how you initiate your rootArray if it's just an empty array then this approach fails and instead you should do:

...
rootArray: [
  ...state.rootArray.slice(0, state.rootArray.length - 1),
  state.rootArray.length > 0
    ? state.rootArray[state.rootArray.length - 1].concat(action.payload.locationObject)
    : [...action.payload.locationObject]
],
...

Otherwise you can just initiate the rootArray to [[]] and use the the first version.

8
  • I still got that error, its like it does not recognised rootArray
    – user3480305
    Commented Jul 22, 2017 at 16:52
  • You should use redux dev tools to debug this, the way you updated the state was wrong to begin with but if state.rootArray is undefined then there is something else wrong. Try and debug it or log what state.rootArray is before dispatching the action.
    – G4bri3l
    Commented Jul 22, 2017 at 16:55
  • I tried, it's just an empty array and it should not fail right
    – user3480305
    Commented Jul 22, 2017 at 16:56
  • I edited, I forgot the length - 1 on the second part, if it's an empty array then it's normal it fails, there is nothing at rootArray[rootArray.length - 1], I suppose your initialState is rootArray: [], change it to rootArray:[[]].
    – G4bri3l
    Commented Jul 22, 2017 at 17:03
  • I did some research of the slice method but I don't understand the reason of using it here. I have adapted the first version of the code from you and it works as intended, but when next event starts, it will just keep concats to the first child of the rootArray rather than starting second childArray and move on from there. I suspect something is off with that slice method though... hmm
    – user3480305
    Commented Jul 22, 2017 at 18:31