In the last lecture, we learned how to immutably update our state and also manage an array here which is
just like object special due to that reference types thing in javascript and you learned that you should
work with it by using concat.
Now I want to handle the case that I delete a result
and for that, we dispatch
DELETE_RESULT here.
Now in the reducer, the easy part of course is to simply add a case for that, add the case DELETE_RESULT
and then we return a javascript object where we first of all copy the old state
and now what,
what do we do with results? Adding an item immutably was possible with concat.
Now you typically remove items from an array by getting the index of the item you want to remove,
so let's say we have it here, could be two, we'll get this dynamically soon, let's for now just do it like
this
and then we could use our array store results and call splice,
if we then pass the id where we want to start as the first argument and the amounts of elements we want
to delete with
the second argument, we take these elements out of the array.
This however mutates the original array and therefore is not how we should do it,
it's not immutable,
so how do we do this in an immutable way then? There are a couple of ways,
I'll show you two.
The first is that you create a copy of your array, so new array could be a new array you create and then
use the spread operator to distribute all the elements in state results into that new array.
With that, you created a copy of the new array, important if the elements in state results were objects
as they actually are, the objects themselves are still pointing to the same objects they did before.
So if you change a property in one of the elements themselves,
just creating a new array like this isn't enough, if you just plan on removing an object though, that
is okay because you won't touch the object, you just remove it from the array,
that's a difference.
So we create a copy of the new array here and then we could simply use that new array here in our splice
operation and then return state where we set results equal to the new array, which is a copy of the old
array but updated
and since we copied it, we never touch the old array.
So this is one way of doing it.
I'm going to comment it out though, the way you see more often is to use the filter method,
now for this you simply can create a new constant which is maybe the updated array, whatever you want
to name it,
you could name a new array of course too and there, you take your original array
state results and call the filter method.
If filter returns a new array, doesn't touch the old one, returns a new one. Filter takes a function
as an input,
the function is executed on each element in the array, it determines whether this element fulfils a
certain condition to make it into the new array which is returned by filter or not.
So we get the individual element as an input here, the element or in our case, the result we could name it
and then we have to return true or false.
If we just return true and this is just the shortcut syntax for an arrow function where if you write
it inline, you can omit the return keyword.
So if you return true, you return this for every element and therefore, you just created a copy of the
old array,
so just a longer form of this syntax.
Of course you don't always want to return true, only for the elements which should be included in the new array.
So since we want to delete element here we return true for every element which doesn't have a certain
ID or which is not at a certain index here.
So if we have the index of the element in the array, we would take a second argument
we get here in this callback function, the index of the element where we are currently at,
so in which this function's executed and there we could simply say return true if that index is unequal
to the index of the element you want to remove it at,
so this is if we're talking about indexes of the elements. Now in our case here, we have a state of objects or
for elements where we have elements of this shape, a value and a unique ID for each element.
So we'll actually receive an ID and we can take this id,
so this is not the index, not the position in the array,
this is an id of the element and since this function here is executed on each element, we don't need
to get information about which index this element is at,
we can just say we return true if the ID of the element in the array we're currently looking at,
we're accessing this id property on each element
therefore, if there is unequal to the ID so excuse me not equal to the ID we're getting with this action.
So for this action, I expect to get a payload of the result element ID or whatever we want to name it,
this is a very long name, you could just use ID but I want to make it really clear where this is coming
from.
So this is a payload of this action and
of course we need to pass this payload.
But first of all let's use this updated array to then set it as results here in the state we return,
it is an array, a totally new thread due to filter which returns true for all elements where the ID is not
equal to the ID we pass with the action.
So now let's pass an ID with the action then
let's go to the counter container and for delete result,
we should now set a property with the same name we're accessing in the reducer
so resultElId,
that's the property I'm accessing here on my action, and this should now simply be the id of the element
we clicked on. Now to get that ID,
we kind of need to get this on this function here,
so there, I somehow need to get this information.
So here, I expect to get the ID passed to this anonymous function here,
this is any arbitrary argument name you can pick and I want to send it along with my action, now of course to
receive that here where we use this property here on delete result,
there we now need to pass that ID.
So here, I'll execute this as an anonymous function
and when this function is executed, then this function will be executed so now I can add parentheses here
because this will now not be executed at the point of time this component renders because it's mapped
or wrapped inside this anonymous function.
And here I can then pass store result ID referring to that new date snapshot.
Now with that if we save all of that and we start adding some results here and I click on the 30, it
is removed,
same of course for the results if we click on them but in an immutable way still.
And you learned a lot of important things here, you learned how to delete elements immutably with filter and
you learned how to pass actions from within your UI to an action by expecting to the argument you get
from the UI in mapDispatchToProps and then passing it along with the action,
and of course by then passing that argument you are expecting here from within your UI by wrapping
this prop you execute in an anonymous function which allows you to pass data along with the function
call.
This is super important and another core building blocks, working immutably on deletes and passing
action payloads from the UI over mapDispatchToProps to the store.