I'm currently working on my first Laravel project using Vue components. My setup includes Laravel 8.x and Vue 2.x running on Windows 10. I came across a helpful video tutorial that I'm trying to follow, but some aspects aren't quite working as expected. Yesterday, the community here assisted me in resolving one issue, but now I've encountered a new challenge.
The video demonstrates making a get request with Axios to retrieve data from a MySQL table within the Vue component. The response from Axios contains the data, which is then assigned to an initially empty array in the component's data() section. The empty array definition looks like this:
todos: '',
The method responsible for executing the Axios get request appears as follows:
getToDos() {
debugger;
axios.get('/todo')
.then(function (res) {
if (res.data.length == 0) console.log("Table is empty");
else {
this.todos = res.data
}
})
.catch(function (error) {
console.log(error);
})
},
In the code snippet above, all of the res.data (an array of objects) is simply assigned to the todos array within the data() section. This logic works seamlessly in the video example, where Laravel 7.x is used, whereas in my case with Laravel 8.x, I encounter an error in the Chrome Debugger:
TypeError: this is undefined
This error points to the line where the assignment occurs (this.todos = res.data). While still getting accustomed to JavaScript, it seems odd to assign an array of objects to a variable initialized as an empty string. Despite my expectations, this mismatch doesn't cause any issues for him - could this be related to the Laravel version difference?
After some research and experimentation, including defining todos as an empty array or initializing it differently, I'm consistently facing the same error whenever attempting to assign something to the todos variable. Even methods such as looping through res.data and pushing each object into todos have been unsuccessful. Any insights on why his approach succeeds while mine fails would be greatly appreciated. My goal is to access res.data in the template for displaying relevant information.
Edit: Provided below is the entirety of the component.
<template>
<div class="container">
<form @submit.prevent="addTask">
<div class="input-group mb-3 w-100">
<input type="text" v-model="form.todo" class="form-control" placeholder="Enter new task" aria-label="Enter new task" aria-describedby="button-addon2">
<div class="input-group-append">
<button class="btn btn-success" type="submit" id="button-addon2">Add new task</button>
</div>
</div>
</form>
<div class="w-25">
<h1 class="text-white">...</h1>
<div v-for="todo in todos" :key="todo.id" class="w-100 text-white">
{{ todo.title }}
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
todos: '',
form: new Form({
title: '',
})
}
},
methods: {
getToDos() {
debugger;
axios.get('/todo')
.then(function (res) {
if (res.data.length == 0) console.log("Table is empty");
else {
this.todos = res.data
// var id = 0;
// var title = '';
// var completed = false;
// for (var ix=0; ix<res.data.length; ix++) {
// id = res.data[ix].id;
// title = res.data[ix].title;
// completed = res.data[ix].completed;
// var oneToDo = new Object(res.data[ix]);
// this.todos.push(oneToDo);
// }
}
})
.catch(function (error) {
console.log(error);
})
},
addTask() {
let data = new FormData();
data.append('todo', this.form.todo);
axios.post('/todo', data)
.then(function (response) {
console.log(response);
this.form.reset;
this.getToDos();
})
.catch(function (error) {
console.log(error);
})
}
},
mounted() {
console.log('ToDoComponent mounted.');
this.getToDos();
}
}
</script>
<style lang="scss" scoped>
.container {
padding-top: 5em;
}
</style>