Momen Alany
Momen Alany

Reputation: 3

Svelte not printing array elements after they're edited

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

Answers (1)

jfhr
jfhr

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

Related Questions