Reputation: 3
Hey I've got this issue while learning svelte, I made this todo app with my simple knowledge in svelte. The problem is I add todos, they get added. I delete todos and they get deleted. But, when I delete multiple todos and try to insert a new todo it doesn't print the todo to the HTML and it gives an error saying:
Error: Uncaught (in promise): Cannot read properties of null (reading 'removeChild')
CODE:
<script>
let todos = []
let heading = 'Enter heading here';
let msg = 'enter your todo here'
let n = 1;
function pushTodo(){
todos = [...todos, new Todo(n, heading, msg)]
n+=1
// Logged todos and n for debugging purposes
console.log('added todo and increased n to'+ n)
console.log(todos)
}
class Todo{
constructor(id, title, msg){
this.id = id
this.title = title
this.msg = msg
}
}
function deleteTodo(id) {
todos.splice(id-1, 1);
document.getElementById(id).remove();
// Logged the todo array for debugging purposes
console.log(todos)
}
</script>
<input type="text" bind:value={heading}>
<input type="text" bind:value={msg}>
<button on:click={pushTodo}>insert todo</button>
{#each todos as {id, title, msg}}
<div id= {id.toString()}>
<h6>{id}</h6>
<h2>{title}</h2>
<h4>{msg}</h4>
<button on:click={()=>{deleteTodo(id)}}>delete</button>
</div>
{/each}
Upvotes: 0
Views: 459
Reputation: 1123
You probably shouldn't be removing HTML elements yourself, svelte does that for you. The problem is, when you call todos.splice
, svelte won't realize that the content of todos
has changed. You need to assign to todos
to achieve that. Try this:
function deleteTodo(id) {
// find the index of the element to remove
const index = todos.findIndex(todo => todo.id === id);
todos.splice(index, 1);
// important: assign todos to itself
// that way svelte realizes that the content of todos has changed!
todos = todos;
// Logged the todo array for debugging purposes
console.log(todos)
}
Upvotes: 2