Search code examples
javascriptcomponentssveltesveltekit

Dynamically creating new component does not work in svelte


So I'm trying to create a new component when a button is pressed.

Here's the place where the button is :

<input type="color" id="todo-color" bind:value={todoColor} />
  <input
    type="text"
    id="todo-content"
    placeholder="Todo"
    bind:value={todoContent}
  />
  <input
    type="checkbox"
    name="isImportant"
    id="is-important"
    bind:checked={todoImportance}
  />
  <button on:click={createTodo}>Create todo</button>

The function that is called is this one:

let todoContent: string;
  let todoColor: string = "#ff0000";
  let todoImportance: any = "default";
  const createTodo = () => {
    todoImportance
      ? (todoImportance = "important")
      : (todoImportance = "default");

    console.log(todoColor, todoContent, todoImportance);

    new Task({
      target: document.querySelector('#basic-todos'),
      todoContent,
      todoColor,
      todoImportance,
    });
  };

The three props must be strings, which is what they are. But I always get undefined for the three props.

I don't know at all what is bad in this code, and if you have a solution or another way to do this i'll take everything :)


Solution

  • Props are passed as the property props:

    new Task({
      target: document.querySelector('#basic-todos'),
      props: {
        todoContent,
        todoColor,
        todoImportance,
      },
    });
    

    Docs

    (Assuming that those are the correct property names.)

    But as noted, this not how to do a to-do list in Svelte. The data should be added to a list and {#each} should be used to create the items declaratively.

    Something along the lines of:

    let items = [];
    // ...
    const createTodo = () => {
      // [collect/prepare data]
    
      items = [...items, item];
    };
    
    {#each items as { content, color, importance }}
      <Task {content} {color} {importance} />
    {/each}
    

    If items are added/removed in the middle the {#each} needs a key, see docs.