So view is doing a lot of work for us,
as we can see already.
Now we've got these two buttons edit and delete,
which are not doing anything yet.
And that is of course, something I want to change.
And let's start with editing. Now,
the goal is, that when we click this button,
we load the correct to do text into this input in the form.
And when the form is then submitted thereafter,
this to do is updated with the newly entered data.
Now to implement this in app.JS,
I'll add a new piece of data
in my returned data object here.
And that's the editedTodoID.
Which initially let's say is null.
Because initially we are not editing any todo.
The goal is to set this as soon as we start editing.
So kind of similar to what we did with just Java script.
When we started editing idea (indistinct)
also stored some element in this case,
in some global variable. Now I want to store the id of,
todo, and not in a global variable,
but in a view managed data property.
But, still kind of comparable. Now for this,
I'll add a new method which could be named startEditTodo.
Or, anything like this. And here, I want to set
this.editedToDoId.
So this data property I want to set this equal to something.
But, equal to what? Well, it would be most convenient,
if this startEditToDo method, however, it may be invoked.
Would get the ToDoId as a parameter value.
So that we can just set it like this.
This would be very convenient.
Thankfully view is very convenient.
What we can do with view is we can go back to the HTML file
and declaratively configure how this startEditToDo
method should be invoked when a certain event occurs.
And specifically we can make it clear that we want the this
Id. For this back here. On this button,
which of course will be replicated multiple times.
Once for every list item. But that's no problem.
We can add another event listener. Again with at.
And then in this case, not submit, but click.
So the name of the event to which we want to listen.
And then here we point at the method that should be executed
In this case startEditToDo.
Now, before when we added @submit,
I mentioned that we could've also written saveToDo
like this. With parentheses. Now, normally in JavaScript,
it's a difference weather you parentheses or not.
Now in view, when adding event listeners in your HTML code,
there is no difference. In both cases,
the method will not be executed immediately.
But, only when this event occurs.
View gives us these two ways of doing one of the same thing.
Because, since we can add parentheses here now.
We can basically pre-configure this function.
We can tell view that we want to have a certain parameter
value when this function will eventually execute,
in the future.
So, for this here to startEditToDo. I can, for example,
pass todo.id. Todo is still this variable here.
And the this variable is one of our todo's
in the todo list.
And, since we add todo's with an ID field here.
We can access this id here. And therefore,
view will make sure that, when this button is clicked,
startEditToDo will be invoked with the concrete ID of
this todo being passed into this method. Therefore,
we can now expect this todoId here.
And store it in this.editedTodoId. Now, that is step one.
Step two is that I want to, pre-populate my input here,
with the text of that, todo. Which, we are editing.
Now, since we have two way binding on that input,
and you'll learn that thanks to two way binding,
changes on enteredTodoText will be reflected back
into the input.
All we have to do is update enteredTodoText.
So therefore now here, I'll set this enteredTodoText
equal to. And now I wanna get the text off the,
todo which we are editing. And for this,
we can find that todo by using this.todos
So our array of todos, and then the find method there.
Find is a built in method which,
you can call on any JavaScript array.
And it allows you to pass a function,
to find. Which will be executed for every item in this array
And, if this function returns true,
it's the item you were looking for.
And it will be returned by this overall method.
If you return false, it will continue looking for an item.
So here we have an individual todoItem. Because again,
this will execute for all the items in this.todos array.
And in this anonymous function, I wanna return true.
If todoItem.id is equal to, todoId.
So I'm going through all the, todo's.
I have a look at the id's of them all.
And if I have an item where it's Id is equal to the,
todoId, I got here, I know that's the item we want to update
So, then I returned true. Therefore,
that item will be returned by find.
It will be stored here in todo.
And here in enteredToDoText, I can now output todo.text
So the text, which is currently stored for that todo.
With that, if we, again, save everything.
If I add a new todo and they then click on edit.
You'll see, that is loaded into the input field here.
Now, currently, if we change that,
we still add a new todo then.
That's of course, not the goal.
So the second step is that we now need to handle the form
submission differently. If we are editing a todo.
For this, we can use a trick,
which we used in our backend code. In our models, a lot.
In saveTodo. Which, is executed when the form is submitted.
We can basically check if this.editedTodoId is truthy.
So, if it's not null. But some other value.
In which case we know that we do have an Id,
which means we are updating a todo.
Else, if it's falsey, if it is for example, null.
We know we don't have an editedTodoId
And therefore we are not editing. But, creating instead.
So this code for pushing a new todo.
Will go into this else branch.
Resetting the form is something I always wanna do.
So, I'll keep that out of if, else.
In the updating case, instead.
I wanna find a todo and update it.
And what we can do here is we can get a, todoIndex.
So the index of the todo item, in the todos array.
By using this.todos.findIndex,
Which works like find, but doesn't return the item itself.
But instead the index of that item.
And then here I get my todoItem and I, again,
wanna return true just as before.
If the todoItem for which this function executes,
has the editedTodoId.
And then now that I got the index,
I can create an updatedTodoItem,
which is a new object. Where I will set the id equal to,
this.todos. For this.todoIndex, which we identified.
Which will give us the existing todo which,
I do want to update. And there I access the Id.
Because, I wanna keep that existing id.
But in my updated new todoItem object,
I can then set the text equal to this.enteredTodoText.
So that we be keep the old id. But we set a new
enteredTodoText. And I'm doing it like this.
So that I create a brand new object in memory,
which ensures that view will definitely pick up this change.
As soon as we replace the existing todoItem
with this new one. Because, now here I can reach out to
this.todos. For the identified todoIndex.
And override the item, which has currently stored
for that index. With my updated, to do item.
With that it will keep its position in the array,
but I will replace it with a new todo item.
With that done. We are creating this updatedTodo,
and we are replacing the old todo,
for that Id that we want to edit with that new updated todo.
And therefore, again, view should do the rest for us.
It should update the dom appropriately for us.
Before we can test this though,
there's just one little gotcha.
Which, this approach would have.
I did mention that view will set this,
this keyword magically to this data object here for us.
It does that. But if you are using this,
this keyword inside of another function,
which you use inside of one of these methods.
Like here in this anonymous function,
then this does not refer to the data object.
View will not be able to remap it in this case.
So therefore here you want to use a simple trick
And get the todoId, with this.editedTodoId.
like this, outside of this function here.
And then you can use to do Id in there.
So this constant, which I created here.
So we just need to create it before we enter this function
so that this still does point at the data object.
And then instead of this function,
We're not using this anymore. But, todoId.
Which stores this id. And hence it will work.
By the way. One other thing I wanna do once we are done,
editing a todo and updating a todo.
I want to set this editedTodoId back to null.
So that the next time we enter anything into the input,
we are not editing an existing to do anymore,
but instead of we'll create a new todo again.
But, with all of that, if we save this code.
If I add a new todo. And then maybe or the second todo
and I then click on edit on a new todo and
add a couple of exclamation marks.
This updates here. And thereafter.
I can again, add new todos.