So in the last video we cycled through this data and we output a snippet of HTML for each person in the array using the each loop. And we can see that over here, everything looks fine.
Now imagine I want to place a button on to each person, and when we click on that button it deletes that person from the array of data over here. And therefore when that happens, we update this data, it should reflect that change in the browser and re-render this list.
Well we can do that. Let me first of all add the button down here. And it's a button, not a button, and we'll say delete inside that. And we need to add on a click handler to this button, right? Because we're going to react to a user clicking it. And inside here we'll reference a function, so for example handle click, but you can call the function whatever you want. And then we need to create that function up here, const handleClick = a function like so.
And then in here, this is where we want to delete the person from people. Right. Now, how do we do this?
The Problem with Direct Handler Invocation
In here, because right now we don't know which person to delete, because we're not passing through this person into the function right here. And we can't access the person over here. I can demo that if I see console.log person like so, we're not going to be able to access that. And if I refresh and delete something, we see person is not defined.
So just because we're referencing a function inside this loop where we have access to person over here doesn't mean we have access to it in the handler function itself. So instead, what we need to do is figure out a way to pass data through into this function as a parameter or argument rather. So for example, you could pass through the person right here, or even person ID. And then we could access the ID in here. But there is a problem with this, and that is that we're now invoking this function automatically. So as we first run this code and we output this template for each person in the array, it's going to automatically invoke this function for every single person without us clicking it, right? Because we're invoking it using these parentheses.
So that means it's going to go ahead, invoke this function, and if we have code in here to delete that person from the array, it's going to automatically delete them straight away, and we don't want that. Let me just demo this in action a little bit. I'm going to log out the ID to the console, and if I save this now, we should automatically see 1, 2, 3. So it's running this function for each person in the array automatically. And we don't want that to happen.
Solution: The Inline Function Wrapper
So what we could do instead is cut this one out and we could create an inline function right here. Let me just delete that closing button; it's automatically added that in for me when I don't need it. But now we have this inline function right here, right? And we're not invoking this function, and I can demo that. I can say console.log and then say clicked me, right? So this is only going to now run when we click on the button because this is not being invoked. We don't have parentheses on the end of it over here. So it's just a reference to a function which runs when we click it.
Now we don't get anything logged here, but if I click on delete, you see 'clicked me', 'clicked me', etc. So this works, but we don't just want to log that to the console. Instead, inside here, we now want to invoke this function. And we can do that by saying handleClick and we can pass through the person dot ID. So now this is fine because now this function is wrapping this function. So this is not getting automatically invoked because it sits inside a function which is not yet invoked until we click on this. So now that would work. Let me just save this and demo it. So we don't get them automatically, but when we click on delete, now we can see the ID of that ninja. So we're now passing it through into this function.
Implementing Deletion with filter() and Reassignment
And we can use that ID to go ahead and delete the person from the array. Now, before we do that, let me just get rid of this curly brace here to open up the code block of the function and this one. Because when we use an arrow function, if we're just doing it all in one line like this, we don't need that curly brace and closing curly brace. So now let's get rid of this console log down here, we don't need that.
But what we do need to do now is update this people array right here. So now I could say people is equal to people—so what the current value is—.filter(). So this is just a regular JavaScript method and it filters through the array so we can remove certain items out. So what this does is take a callback function right here. So let me just create this function, and this function then takes in each person as we cycle through it. Right? So the filter method cycles through the array and fires a callback function for each person. and we take that person in right here. And by the way, you can call this what you want, you can call it a or b or whatever you want. It makes sense to me to call it person.
And then inside here we return true or false. If we return true, then it keeps that person in the array. If we return false, then it removes that person from the array. So if I now say, well we'll take the person and get the ID and we'll check if that is not equal to the ID. Because if they're not equal, then we want to keep that person in the array. Remember, we pass through the ID of the person that we click on right here. So say we pass through two, it means we've clicked on this one, right? So we filter the array, we fire a callback function for each item, it checks if the ID that we clicked on is not equal to the ID we pass through. If they're not equal, then it will return true and we'll keep that in, and that's right. Now if they are equal, this will return false, therefore it will filter that item out of the array. Does that make sense? Cool.
So this right here returns a new array without the filtered item. And then what we're doing is updating the value of people with that filtered array. We have to reassign because Svelte looks for this reassignment—the equal sign if you like—to check that something's been updated. We can't just do this right here because that is not actually going to work. We're not reassigning any kind of data. Instead, we need to explicitly reassign the data based on the results of this. And then when Svelte sees this reassignment and takes the value of people, then it reruns to output the updated list down here. So if we save this, cross our fingers, and test this... let's try deleting Mario and boom, it goes. Yoshi, Luigi. And now there are no people to show. So there we go my friends, that's how we can pass through an argument to a click handler or any other kind of handler function where an event occurs: we wrap it inside an inline function which is not automatically invoked when the code runs.
Accessing the Event Object
Now one more thing. I said that we can take in an event object in any handler when we register it, right? We did that before, and this is no different. But this time the event object doesn't go directly in here because this is now no longer the direct handler, this is just a function we're invoking inside the handler, which is this now. So we take in the event object right here. And then if you wanted to, you could pass it in as an argument into this handleClick function. We could take it in here then as a parameter, and if we wanted to use it, we could. So console.log(e) just to see that this works.
Save it and delete, and now we can see we get this event object with information about the events right here. We don't need it in our case, so I'm going to get rid of it again, but if you want to use it, that is how you would use it. Pass it through to the inline function and then into your custom handler if you need it.
Okay, so that is inline functions. In the next video, we're going to take a look at conditionals in our template.