Update Data in a List without Mutations

Share this video with your friends

Send Tweet

We’ll build small, focused functions to select an object from a list, apply updates to an object and replace an item in a list, avoid mutations to those objects along the way by returning new items that reflect our changes. We’ll verify this behavior by following a test driven approach using Jest.

Joel Regen
Joel Regen
~ 8 years ago

how do you get the multiple cursor to be placed on the test.skip locations without manually placing it there with 'option-click' ?

Andy Van Slaars
Andy Van Slaars(instructor)
~ 8 years ago

Joel,

In atom, you can trigger the select-next function with cmd+D. If your cursor is in the middle of a word, the first cmd+D will select the current word, then each subsequent use of cmd+D will select the next occurrence of that word. If you want to select something more involved that isn't automatically selected with the first cmd+D, use the mouse or other keys to select that entire series of chars, then you can use cmd+D to select that combination elsewhere in the file.

Hope this helps!

Iain Maitland
Iain Maitland
~ 8 years ago

I am getting an error when I run npm test

 FAIL  src/lib/todoHelpers.test.js
  ● Test suite failed to run

    Couldn't find preset "es2015" relative to directory "/home/johndoe"

Can anyone help me out. I don't think it's an issue with the tut, just me messing things up...

Andy Van Slaars
Andy Van Slaars(instructor)
~ 8 years ago

Iain,

Are you running the tests from your home directory instead of the project directory? That's what it looks like at a glance. If that's not it, I might need some more info to help you work this out. Let me know.

Seb Pearce
Seb Pearce
~ 8 years ago

I tried writing the updateTodo helper myself before seeing how it was done in the video, and I came up with:

export const updateTodo = (list, updated) =>
  list.map(todo => todo.id === updated.id ? updated : todo);

I was surprised to see something very different in the video:

export const updateTodo = (list, updated) => {
  const updatedIndex = list.findIndex(item => item.id === updated.id)
  return [
    ...list.slice(0, updatedIndex),
    updated,
    ...list.slice(updatedIndex+1)
  ]
}

Is there any benefit to the longer version using slice, or gotchas with using map?

Andy Van Slaars
Andy Van Slaars(instructor)
~ 8 years ago

Seb,

Using map here is fine and there are no gotchas that I'm aware of, nor can I think of any specific benefits to the more verbose approach.

I mainly used the spread operator here to remain consistent with the way I was handling addTodo, toggleTodo and removeTodo.

I like the use of map here personally and have used this approach before, though I suppose one could argue that map implies a transformation is being applied to each item in the list.

The bottom line here is that either way is fine and both accomplish the same goal so I say use the style you prefer.

Hope this helps.

Kevin Pinny
Kevin Pinny
~ 7 years ago

Very good course so far. I'm learning some basic React, loving it so far. I like how the course gives also some introduction to TDD and Immutability, something I currently struggle to get into. Props to you!

Andy Van Slaars
Andy Van Slaars(instructor)
~ 7 years ago

kefkef5,

I'm really glad you're getting so much out of it! Thanks for the kind feedback :)

supernarwen
supernarwen
~ 7 years ago

I just could not get this part. What is this code returning? Aren't we returning whole list here?

export const updateTodo = (list, updated) => {
  const updatedIndex = list.findIndex(item => item.id === updated.id)
  return [
    ...list.slice(0, updatedIndex),
    updated,
    ...list.slice(updatedIndex+1)
  ]
}
Nirmala
Nirmala
~ 5 years ago

why ...list.slice(updatedIndex+1) ? I tested without it and it really did not made any difference