Extract ToDoList component0:00
Okay let's continue and extract one more component here. So we'll extract a to-do list which will have the actual list of to-dos. We'll have this container here with the check all and items remaining and also the filters and clear completed. So in my markup I believe these are three separate DOM nodes. So I have the unordered list here for the list of to-dos. I have this check all container for the second container here and then I have other buttons container for the last one. Now Svelte does support multiple DOM nodes but for me I feel more comfortable having a root DOM node so let's do that. So let's go here let's add say a div and then I'll close it out down here. So right here this should be the end of it and I'll save that. Okay now we can
add say a div and then I'll close it out down here. So right here this should be the end of it and I'll save that. Okay now we can select all that. Let's cut that out. Let's make a new component named ToDoList. Okay let me just bring back my sidebar here. Let's go ahead and create that to-do-list.svelte. Paste in our markup. Let me hide the sidebar again. Let's go back to app.svelte. Make sure to import that. Let's go ahead and save that and let's save our to-do.svelte as well. Okay now we're getting a white screen because a lot of the state in here depends on methods that live on app.svelte. So on the parent component. So let's start from the top here. Let's start with the import for our transitions so we can
Pass state via props1:27
depends on methods that live on app.svelte. So on the parent component. So let's start from the top here. Let's start with the import for our transitions so we can grab that from the app.svelte. Let's grab this. Actually I think we don't need it here anymore because they are extracted to their own components now. So let me just grab this import. Let's paste it in our to-do list. Make sure to add a script section. Okay let's paste that in and we only need fade and fly. Okay now for some of the state within our to-do list, remember to-do list is the child component. We only need to read data from the parent component and in these cases we can just pass them in as props. So let's pass in a few props here. So remember to accept props we can say export let and then the name of the
and in these cases we can just pass them in as props. So let's pass in a few props here. So remember to accept props we can say export let and then the name of the prop. So one of them is going to be filteredToDos. The other one is going to be remainingToDos. Not sure what I named it. remaining. Yeah remainingToDos. So this was a count of the remainingToDos. So let's pass that in as well. remainingToDos. Okay and we also need to read the current filter. We'll be updating that as well but for now let's just read in the default current filter. So currentFilter. Okay let's save that and let's go ahead and pass that in from the parent component. So for our to-do list let's pass them in as props here. So the first one was filteredToDos. We can say filterToDos equals filteredToDos.
the parent component. So for our to-do list let's pass them in as props here. So the first one was filteredToDos. We can say filteredToDos equals filteredToDos. Now if the name is the same then you can get rid of the attribute. So I believe Prettier will handle that case for us. So let me save this and it does. And you can see the app is rendering in the browser now. Let's also pass in the remaining to-dos. Okay and the last one was currentFilter. Okay so remember these pieces of state live on this parent component. We're going to emit events from the child ToDoList component which may update the state and when this state is updated the child ToDoList component will be re-rendered with that new data. So let's go ahead and work on re-adding the
Wire actions with events3:32
the state and when this state is updated the child to-do list component will be re-rendered with that new data. So let's go ahead and work on re-adding the functionality. So let's start with the checkAll button here. And again we'll start from the to-do list. So let's look for that button here. Check all. And you can see before it was calling the checkAllTodos method which is now in the parent component. But let's go ahead and define our own checkAllTodos method within this component here. So let's go into our script. Let's add that. checkAllTodos. No params. And just like before we can dispatch an event. Listen for it in the parent component and then call the appropriate method in there to update our to-do's. So let's go back to our ToDoForm. Let's grab all of this
in the parent component and then call the appropriate method in there to update our to-do's. So let's go back to our todo form. Let's grab all of this including the imports. Okay let's go back here. Let's go ahead and paste that in. Actually I'll just overwrite this. We don't need this. This is checkAllTodos. Let's dispatch an event named checkAllTodosDispatched. We don't need to pass anything for params in this case. You don't need this. So let's go ahead and save that. Let's go back to our parent. In the TodoList let's accept or listen for that event. So let's say on checkAllTodosDispatched. Let's call the method that already exists here. So the method is called checkAllTodos right here. Okay let's save that and let's see if checkAll
Let's call the method that already exists here. So the method is called checkAll to-do's right here. Okay let's save that and let's see if checkAll works now. And it does. Cool. You can also see that the items remaining also updated which caused a re-render of the to-do list component with the correct data being shown here. So it's pretty much the same for all of the other features. Dispatch an event from the to-do list component. Listen for it in the parent component and then call the method that does the work. So let's work on clearCompleted here. Let's look for that clearCompleted. Okay let's make a method called clearCompleted here. So back to our script. Let's add that method here. clearCompleted doesn't need any params. We're dispatching a similar event
a method called clearCompleted here. So back to our script. Let's add that method here. clearCompleted. Doesn't need any params. We're dispatching a similar event but let's name it clearCompletedDispatched. Let's listen for that in the parent. So let's duplicate this. It should be clearCompletedDispatched. Okay and I believe the method for that is named clearCompleted. Okay let's try that out. Let's clear these two and it does work. Now let's work on deleting to-do's. So that doesn't work now. Let's do the same thing. So back to our to-do list. Let's look for that button. So we have this deleteTodo method that takes in a todoId. So let's define that up here. So deleteTodo takes in an ID and again we're just dispatching an event. Now it needs params. So let's pass those through.
ID. So let's define that up here. So deleteToDo takes in an ID and again we're just dispatching an event. Now it needs params. So let's pass those through. So the ID should be the ID being passed through. We don't need this. Okay let's go ahead and listen for that in the parent. I forgot to change the name here. So let's say deleteToDoDispatched. Let's save that. Let's duplicate this. Let's make sure to rename this. And let's call the appropriate method. So in this case it needs a param. So let's pass in a callback. And the method is deleteToDo. We actually need to accept the event here. Then we can pass in the event.detail.ID in this case. Okay let's save that. And let's see if delete works. And it does. Cool. Let's work on our filters here. So back to toDoList. Let's
Implement filter updates7:12
detail dot ID in this case. Okay let's save that. And let's see if delete works. And it does. Cool. Let's work on our filters here. So back to to-do list. Let's go to the filter section. So here we were just updating the state directly. But now since the current filter lives on the parent component, let's just call a method instead. So this one will be updateFilter. And we're updating it to all. Let's do the same for the others as well. So this one will be for active. So let's replace that. And this one will be for completed. Okay. Let's go ahead and define this method up here. So function updateFilter takes in the filter. And again we're just dispatching
Let's go ahead and define this method up here. So function updateFilter takes in the $filter. And again we're just dispatching an event here. So let's grab this. We are dispatching an event named updateFilterDispatched. And we're passing through the $filter here. Let's go ahead and listen for that on the parent. So again it's pretty much the same as this. So on updateFilterDispatched. Let's call an updateFilter method which doesn't exist. So we'll define that in a second. And then we're passing through the $filter. Let's go ahead and define this method up here in our script. So we'll put it down here somewhere. Anywhere is fine. Here's fine. Let's say function updateFilter takes in the $filter. And we're just updating the
Enable todo editing events8:41
we'll put it down here somewhere. Anywhere is fine. Here's fine. Let's say function updateFilter takes in the filter. And we're just updating the currentFilter state here. So currentFilter equals the filter. So if I did that correctly our filter should work now. So all is default. active shows to to-dos that are not completed. And completed shows the checked to-dos. Okay let's continue and work on editing to-dos. So again when we double click we want to be able to edit our to-dos. So let's go back to our toDoList. Let's look for our double click. Let's go ahead and define this editToDo method. And I guess we can do doneEdit and doneEditKeyDown as well. So let's grab this. Let's define this method up here. So it's editToDo. We're passing in a toDo here. Let's do
can do doneEdit and doneEditKeyDown as well. So let's grab this. Let's define this method up here. So it's editTodo. We're passing in a todo here. Let's do the same for doneEdit and doneEditKeyDown. So let me just duplicate this twice. This is doneEdit. It's also taking in a todo and this one is doneEditKeyDown. And again same process. We're just dispatching an event. So let's grab this. This one will be named editTodoDispatched. And we're passing through the todo here. And the same for the other ones but with the appropriate names. Okay so I changed the names. I think for doneEditKeyDown we have to pass in the key being pressed. But for now let's work on the first todo. So editTodo and doneEdit. Let me save this. Let's go back to our app's felt. Let's go back to our
yet because we have to pass in a key here. So if I hit enter here it doesn't work yet or escape as well. So let's go back to our to-do list. Let's go back to where we're calling doneEditKeyDown. So we are passing in the event here. So let's go back to the method and let's accept the event here. And let me just console.log the event.key to make sure it's listening for key pressed down. So let me save this. Let's go ahead and double-click this. Let's press enter here and the key down does work. So now when we're passing it into the parent component let's make sure to pass in the key being pressed. So let's say key is event.key. Okay let's delete this. Let's save this back to our app.svelte and for that method we're calling. I forgot to change the
let's say key is event.key. Okay let's delete this. Let's save this back to our apps/Controller.php file and for that method we're calling. I forgot to change the name so let's do that first. So doneEditKeyDown and that should call a method named doneEditKeyDown. And let me just take a look at that method doneEditKeyDown. So in this case we took the event in here but now we're passing through the actual key. So we can get rid of the event here. So let me just use multiple cursors. Just remove that. Okay and we can just accept the key here. Okay so let's make sure I did that correctly. We have to pass in the key here as well. So event.detail.key and hopefully I did that correctly. So let me save that. Let me just hide DevTools here. Let's try editing this one again.
So event.detail.key and hopefully I did that correctly. So let me save that. Let me just hide DevTools here. Let's try editing this one again. Press enter here. It does commit. Let's try the case when we don't want to commit. Don't want to hit escape. The changes are reverted. Let's also make sure the case where we don't enter anything works as well. And it does. Cool. So now all of our to-do functionality is working as before. So whenever you need to read data from a parent component into a child component you can pass down props like we're doing here. And whenever you need to update some state that lives in the parent component. So in this case the state we want to update is the toDos array. And all of those methods live on the parent App Component.
Recap and git commit13:27
how we can make use of a global store so we can read and update global state from any of our components without the need to pass events and props around. But for now let's go ahead and make a commit here. Let me stop my server say git add git commit this is episode 6 component communication with events part 2.
