To see what’s happening we can log the todos array from the checkAllTodos() function to the console.
- Update your existing checkAllTodos() function to the following:
- Go back to your browser, open your DevTools console, and click Check All/Uncheck All a few times.
You’ll notice that the array is successfully updated every time you press the button (the todo objects’ completed properties are toggled between true and false), but Svelte is not aware of that. This also means that in this case, a reactive statement like $: console.log(‘todos’, todos) won’t be very useful.
To find out why this is happening, we need to understand how reactivity works in Svelte when updating arrays and objects.
Many web frameworks use the virtual DOM technique to update the page. Basically, the virtual DOM is an in-memory copy of the contents of the web page. The framework updates this virtual representation, which is then synced with the “real” DOM. This is much faster than directly updating the DOM and allows the framework to apply many optimization techniques.
These frameworks, by default, basically re-run all our JavaScript on every change against this virtual DOM, and apply different methods to cache expensive calculations and optimize execution. They make little to no attempt to understand what our JavaScript code is doing.
Read more: Eunuchworld
Svelte doesn’t use a virtual DOM representation. Instead, it parses and analyzes our code, creates a dependency tree, and then generates the required JavaScript to update only the parts of the DOM that need to be updated. This approach usually generates optimal JavaScript code with minimal overhead, but it also has its limitations.
Sometimes Svelte cannot detect changes to variables being watched. Remember that to tell Svelte that a variable has changed, you have to assign it a new value. A simple rule to keep in mind is that The name of the updated variable must appear on the left-hand side of the assignment.
For example, in the following piece of code:
Svelte won’t update references to obj.foo.bar, unless you follow it up with obj = obj. That’s because Svelte can’t track object references, so we have to explicitly tell it that obj has changed by issuing an assignment.
In our checkAllTodos() function, when we run:
Read more: Enumerate vs range len python
Svelte will not mark todos as changed because it does not know that when we update our t variable inside the forEach() method, we are also modifying the todos array. And that makes sense, because otherwise Svelte would be aware of the inner workings of the forEach() method; the same would therefore be true for any method attached to any object or array.
Nevertheless, there are different techniques that we can apply to solve this problem, and all of them involve assigning a new value to the variable being watched.
As we already saw, we could just tell Svelte to update the variable with a self-assignment, like this:
This will solve the problem. Internally Svelte will flag todos as changed and remove the apparently redundant self-assignment. Apart from the fact that it looks weird, it’s perfectly OK to use this technique, and sometimes it’s the most concise way to do it.
We could also access the todos array by index, like this:
Read more: System net requestexception name or service not known
Assignments to properties of arrays and objects — e.g. obj.foo += 1 or array[i] = x — work the same way as assignments to the values themselves. When Svelte analyzes this code, it can detect that the todos array is being modified.
Another solution is to assign a new array to todos containing a copy of all the to-dos with the completed property updated accordingly, like this:
In this case we are using the map() method, which returns a new array with the results of executing the provided function for each item. The function returns a copy of each to-do using spread syntax and overwrites the property of the completed value accordingly. This solution has the added benefit of returning a new array with new objects, completely avoiding mutating the original todos array.
All of these solutions involve an assignment in which the updated variable is on the left side of the equation. Any of this techniques will allow Svelte to notice that our todos array has been modified.
Choose one, and update your checkAllTodos() function as required. Now you should be able to check and uncheck all your to-dos at once. Try it!