Search code examples
sveltesvelte-3svelte-componentsvelte-2

What causes this "cannot read property 'title' of undefined" bug in my Svelte app?


I am working on a small Todo app in Svelte for learning purposes (Im new to Svelte).

In App.svelte I import the TodoItem component loop a todosarray:

import TodoItem from './TodoItem.svelte';
//more code

{#each todos as t, index}<TodoItem />{/each}

In TodoItem.svelte I have:

<script>
    import { createEventDispatcher } from 'svelte';
    export let index;
    export let t;
    export let id;
    export let title;
    export let completed;
    
    function deleteTodo(tid){
        let itemIdx = todos.findIndex(x => x.id == tid);
        todos.splice(itemIdx,1);
        todos = todos;
    }
    
    function editTodo(tid) {
        isEditMode = true;
        let itemIdx = todos.findIndex(x => x.id == tid);
        currentToDo = todos[itemIdx];
    }
    
    function completeTodo(tid){
        let itemIdx = todos.findIndex(x => x.id == tid);
        let todo = todos[itemIdx];
        todo.completed = !todo.completed;
        todos = todos;
    }
</script>

<tr>
    <td>{index + 1}</td>
    <td class="{t.completed == true ? 'completed' : ''}">{t.title}</td>
    <td class="text-center"><input type="checkbox" checked="{t.completed}" on:change={completeTodo(t.id)}></td>
    <td class="text-right">
        <div class="btn-group">
            <button on:click="{() => editTodo(t.id)}" class="btn btn-sm btn-primary">Edit</button>
            <button on:click="{deleteTodo(t.id)}" class="btn btn-sm btn-danger">Delete</button>
        </div>
    </td>
</tr>

For a reason I have not figured out, I get an Cannot read property 'title' of undefined error in this component, as this REPL shows.

What am I doing wrong?


Solution

  • The error "cannot read something of thing" means that you are trying to access the property "something" of a variable named "thing".
    So in your case.. "Cannot read property title of undefined" means you are trying to access the property "title" of something that is not defined.
    In your code I can only see one object that you are trying to access the property "title".
    t.title.
    So the error is saying that the t variable is not defined.
    Your offending line of code is:
    {#each todos as t, index}<TodoItem />{/each}.
    because you are not sending the TodoItem it the t variable which it is expecting.
    Change it to:
    {#each todos as t, index}<TodoItem t/>{/each}