I'm developing simple TodoList app using Laravle 9, VueJS 3, Vite bundler - all this built in tools when creating Laravel fresh installation.
In app user can make CRUD operations with TodoItem and all user data saved on server, so data preserved on page refresh.
Application almost finished, unless some strange bug: when I run app on local machine - all works perfectly, but when I deploy it on Heroku and open in browser - I see no todos in UI, although during installation some example todo rows already seeded in db.
I examined API - it returns data as expected:
[
{
"id": 67,
"text": "Thing1",
"is_done": false,
"is_urgent": false,
"created_at": "2022-08-24T09:16:37.000000Z",
"updated_at": "2022-08-24T09:16:37.000000Z"
},
{
"id": 68,
"text": "Buy milk",
"is_done": false,
"is_urgent": false,
"created_at": "2022-08-24T09:16:37.000000Z",
"updated_at": "2022-08-24T09:16:37.000000Z"
},
{
"id": 69,
"text": "Thing2",
"is_done": true,
"is_urgent": false,
"created_at": "2022-08-24T09:16:37.000000Z",
"updated_at": "2022-08-24T09:16:37.000000Z"
},
{
"id": 70,
"text": "Thing3",
"is_done": true,
"is_urgent": false,
"created_at": "2022-08-24T09:16:37.000000Z",
"updated_at": "2022-08-24T09:16:37.000000Z"
}
]
When I create new Todo in textbox request sends to server, and data saved on remote server - but on page refresh - I again get empty data in UI, althout i see in that data loaded
This is my App.vue
<template>
<div class="container mt-5" style="padding-left: 0 !important;">
<h3><span class="fw-bold text-warning">Simple</span> TodoList</h3>
</div>
<div class="container mt-4">
<div class="row">
<!-- Simple todos -->
<div class="col-md-6 py-3" style="border: 1px solid #ddd">
<p>Todos ({{ simpleTodos.length }})</p>
<ul>
<li :id="todo.id"
:key="todo.id"
:class="{ 'text-decoration-line-through': todo['is_done'], 'todo-item__link': true }"
v-for="todo in simpleTodos"
@click="contentVisible === todo.id ? contentVisible = false : contentVisible = todo.id">
{{ todo.text }}
</li>
</ul>
<input type="text" name="todo" id="todo.new" @keydown.enter="addTodo" placeholder="Type todo and press Enter" />
</div>
<!-- Urgent todos -->
<div class="col-md-6 py-3" style="border: 1px solid #ddd">
<p>Todos <span :class="{ 'text-danger': urgentTodos.length >= 3}">({{ urgentTodos.length }})</span></p>
<ul>
<li :id="todo.id"
:key="todo.id"
:class="{ 'text-decoration-line-through': todo['is_done'], 'todo-item__link': true }"
v-for="todo in urgentTodos"
@click="contentVisible === todo.id ? contentVisible = false : contentVisible = todo.id">
{{ todo.text }}
</li>
</ul>
</div>
</div>
</div>
</template>
<script>
import {getAllTodos, createTodo, removeTodo, toggleTodoCompleteStatus, toggleTodoUrgentStatus} from '../services/TodoService'
export default {
name: "App",
data() {
return {
allTodos: [],
contentVisible: false
}
},
mounted() {
this.getAllTodos();
},
computed: {
simpleTodos() {
return this.allTodos.filter(todo => todo['is_urgent'] === 0);
},
urgentTodos() {
return this.allTodos.filter(todo => todo['is_urgent'] === 1);
}
},
methods: {
getAllTodos()
{
getAllTodos()
.then(todos => {
console.log(todos)
this.allTodos = todos
})
.catch(err => {
alert('Error happened while fetching todos!');
console.error(err)
});
},
addTodo(e)
{
// return if value is empty
if(e.target.value.trim().length === 0)
return false;
const clientTodo = { text: e.target.value, is_done: 0, is_urgent: 0 }
createTodo(clientTodo).then(({ todo }) => {
this.allTodos.push(todo);
e.target.value = "";
});
},
}
}
</script>
<style scoped>
.todo-item__link {
cursor: pointer;
position: relative;
}
.todo-item__link .text-primary {
position: absolute;
padding-left: 10px;
}
.todo-item__link:hover {
text-decoration: underline;
}
</style>
I tring to use Vue Debug Tools - it shows empty allTodos list.
I don't unsderstand why this.getAllTodos() doesn't update state on mount