1

Trying to do immutable way of pushing an array into existing array but somehow my code is not working.

function insertItem(array, action) {
  return [
    ...array.slice(0, action.index),
    action.item,
    ...array.slice(action.index)
  ]
}

const ori_arr = [{
  id: 1,
  name: 'james',
  age: 10
}, {
  id: 2,
  name: 'terrance',
  age: 20
}]

console.log(insertItem(ori_arr, {
  action: {
    index: 1,
    item: {
       id: 3,
       name: 'she',
       age: 44
    }
  }
}))

possibly wrong at the index part.

7
  • 3
    Not 100% sure I understand what you are trying to achieve, though I believe you'd want to use action.action.index - not action.index because that doesn't exist. Commented Nov 14, 2017 at 9:56
  • 1
    Yup, the {action: ... } in the function call is too much. You just want {index:1, item:...} Commented Nov 14, 2017 at 9:57
  • However it is very important to note that you are performing a shallow copy, so even though you have a new array, modifying the new one may cause issues (I'm not certain how const affects it) Commented Nov 14, 2017 at 9:57
  • Regardless of how you fix this, I recommend against using the same variable for both your input object and for the key. Commented Nov 14, 2017 at 10:00
  • 1
    @axiac nope, I've said earlier I want to do the immutable way, I can't use splice. Commented Nov 14, 2017 at 10:09

2 Answers 2

2

Since the object you want to add has a nested property action, you might want to use destructuring to get just the action key as your inserItem function's argument.

const insertItem = (array, { action }) => [
   ...array.slice(0, action.index),
   action.item,
   ...array.slice(action.index),
];

const ori_arr = [{
  id: 1,
  name: 'james',
  age: 10
}, {
  id: 2,
  name: 'terrance',
  age: 20
}]

console.log(insertItem(ori_arr, {
  action: {
    index: 1,
    item: {
       id: 3,
       name: 'she',
       age: 44
    }
  }
}))

Hovever, if you'd prefer to avoid destructuring, just change the name of your second argument in the insertItem function for e.g. obj and then just add obj before every action.index in your function:

const insertItem = (array, obj) => [
   ...array.slice(0, obj.action.index),
   obj.action.item,
   ...array.slice(obj.action.index),
];
Sign up to request clarification or add additional context in comments.

2 Comments

does the order matter here? how is the order works? the new item got pushed to the last item or in the middle?
@JaneEmelia Yes, it does since you are slicing the original array on (0, 1), then you are inserting the new object and then adding the missing rest of the original array. If you want to add it at the end, you just need [...array, action.item].
0

You're passing the parameters incorrectly:

console.log(insertItem(ori_arr, {
  action: {
    index: 1,
    item: {
       id: 3,
       name: 'she',
       age: 44
    }
  }
}))

instead pass it without the action object:

console.log(insertItem(ori_arr, {
    index: 1,
    item: {
       id: 3,
       name: 'she',
       age: 44
    }
}))

If you tried logging it you'd see that inside your function insertItem you have a param called action, it's value (when you call it) is

action = { action: { index: 1, item: { id: 3, name: 'she', age: 44 }}}

so when you try to access action.item it doesn't exist.

Another solution would be to change your function to

function insertItem(array, action) {
  return [
    ...array.slice(0, action.action.index),
    action.action.item,
    ...array.slice(action.action.index)
  ]
}

1 Comment

is there any case where slice is needed here? usually when user clicked a button to add something, either we push the new item to the start or to the end of the list, correct?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.