I study Vuejs (first of all, I donβt know much about Laravel), and I'm trying to create a simple voting system for some tasks. I managed to add tasks, edit them and delete, but when I added the upvote / downvote material, the number of votes did not change.
So here are the Laravel routes\api.php in routes\api.php :
Route::group(['middleware'=>'api'],function(){ Route::get('tasks', function(){ return \App\Task::latest()->orderBy('created_at', 'desc')->get(); }); Route::get('task/{id}', function($id){ return \App\Task::findOrFail($id); }); Route::post('task/store', function(Request $request){ return App\Task::create(['body' => $request->input(['body'])]); }); Route::patch('task/{id}', function(Request $request, $id){ return \App\Task::findOrFail($id)->update(['body' => $request->input(['body'])]); }); Route::delete('task/{id}', function($id){ return \App\Task::destroy($id); }); Route::get('task/{id}/votes', function($id){ return \App\Task::findOrFail($id)->votes->get(); }); Route::patch('task/{id}/votes', function(Request $request, $id){ return \App\Task::findOrFail($id)->update(['votes'=> $request->input(['votes'])]); }); });
The move for the Tasks table looks like this (I used sqlite):
Schema::create('tasks', function (Blueprint $table) { $table->increments('id'); $table->text('body'); $table->integer('votes')->default(1); $table->timestamps(); });
This is the Tasks component template for Vue:
<h1>My Tasks</h1> <hr> <h4>New Task</h4> <form action="#" @submit.prevent="edit ? updateTask(task.id) : createTask()"> <div class="input-group"> <input type="text" name="body" v-model="task.body" v-el:taskinput class="form-control" autofocus> <span class="input-group-btn"> <button type="submit" class="btn btn-success" v-show="!edit">New Task</button> <button type="submit" class="btn btn-primary" v-show="edit">Edit Task</button> </span> </div> </form> <hr> <hr> <h3>All Tasks</h3> <ul class="list-group"> <li class="list-group-item" v-for="task in list"> {{ task.body }} <button class="btn-success btn-xs" @click="upvote(task.id)" :class="{disabled: upvoted}">Upvote</button> <span class="label label-primary">{{ task.votes }}</span> <button class="btn-danger btn-xs" @click="downvote(task.id)" :class="{disabled: downvoted}">Downvote</button> <span class="pull-right"> <button class="btn-primary btn-xs" @click="showTask(task.id)">Edit Task</button> <button class="btn-danger btn-xs" @click="deleteTask(task.id)">Delete Task</button> </span> </li> </ul>
And finally, the Vue script:
export default{ data(){ return{ edit: false, list: [], task: { id: '', body: '', votes: Number }, upvoted: false, downvoted: false } }, ready: function () { this.fetchTaskList(); }, methods:{ fetchTaskList: function () { this.$http.get('api/tasks').then(function (response) { this.list = response.data }); }, createTask: function () { this.$http.post('api/task/store', this.task); this.task.body = ''; this.edit = false; this.fetchTaskList(); }, updateTask: function (id) { this.$http.patch('api/task/' + id, this.task); this.task.body=''; this.edit = false; this.fetchTaskList(); }, showTask: function (id) { this.$http.get('api/task/' + id).then(function (response) { this.task.id = response.data.id; this.task.body = response.data.body; }); this.$els.taskinput.focus(); this.edit = true; }, deleteTask: function (id) { this.$http.delete('api/task/' + id); this.fetchTaskList(); }, updateVotes: function (id, votes) { this.$http.patch('api/task/'+id+'/votes', votes); }, upvote: function (id) { this.$http.get('api/task/'+id+'/votes').then(function (response) { this.task.id = response.data.id; this.task.votes = response.data.votes + 1; updateVotes(this.task.id, this.task.votes); }); this.upvoted = !this.upvoted; this.downvoted = false; }, downvote: function (id) { this.$http.get('api/task/'+id+'/votes').then(function (response) { this.task.id = response.data.id; this.task.votes = response.data.votes - 1; updateVotes(this.task.id, this.task.votes); }); this.upvoted = false; this.downvoted = !this.downvoted; }, } }
I assume the error is somewhere in the Vue script, or I declare the wrong voices (votes: number?), Or I cannot call the updateVotes function from the upvote and downvote functions, like me.
Edit: Still not working, but I have Vue.js devtools and it definitely recognizes votes: https://snag.gy/sE5gp6.jpg
... but in a very strange way. When I press upvote, the voices in devtools change to "11" and not to 1. When I press downvote, it returns to 0. However, it does not change in the view. This is all after I made the changes:
updateVotes(this.task.id, this.task.votes);
To:
this.updateVotes(this.task.id, this.task.votes);
.. as suggested by user Dan, and after the change:
upvote: function (id) { this.$http.get('api/task/'+id+'/votes')
To:
upvote: function (id) { this.$http.get('api/task/'+id)
since I think I used to get only votes and then viewed them as a Task object for the rest of the function. The same goes for the downvote function.
Here is what now appears in the console:
vue-resource.common.js? d39b: 966 PATCH http: // localhost: 8000 / api / task / 8 / votes 500 (Internal server error) (anonymous function) @vue -resource.common.js? d39b: 966Promise $ 1 @ vue-resource.common.js? d39b: 192xhrClient @ vue-resource.common.js? d39b: 927sendRequest @ vue-resource.common.js? d39b: 1060exec @ vue- resource.common.js? d39b: 1017next @ vue-resource.common.js? d39b: 1042before @ vue-resource.common.js? d39b: 881exec @ vue-resource.common.js? d39b: 1017next @ vue-resource. common.js? d39b: 1042timeout @ vue-resource.common.js? d39b: 920exec @ vue-resource.common.js? d39b: 1017next @ vue-resource.common.js? d39b: 1042method @ vue-resource.common. js? d39b: 895exec @ vue-resource.common.js? d39b: 1017next @ vue-resource.common.js? d39b: 1042body @ vue-resource.common.js? d39b: 802exec @ vue-resource.common.js? d39b: 1017next @ vue-resource.common.js? d39b: 1042jsonp @ vue-resource.common.js? d39b: 867exec @ vue-resource.common.js? d39b: 1017next @ vue-resource.common.js? d39b: 1042header @ vue-resource.common.js? d39b: 903exec @ vue-resource.common.js? d39b: 1017next @ vue-resource.common.js? d39b: 1042cors @ vue-resource.common.js? d39b: 777exec @ vue-resource.common.js? d39b: 1017next @ vue-resource.common.js? d39b: 1042 (anonymous function) @ VM56: 32exec @ vue-resource.common.js? d39b: 1017 (anonymous function) @ vue-resource.common.js? d39b: 1045Promise $ 1 @ vue-resource.common.js? D39b: 192Client @ vue-resource.common.js? D39b: 1010Http @ vue-resource.common.js? D39b: 1152 (Anonymous function) @ vue-resource.common. js? d39b: 1188updateVotes @ Tasks.vue? 34c5: 94 (anonymous function) @ vue.common.js? 4a36: 216 (anonymous function) @ Tasks.vue? 34c5: 102 localhost /: 1 Unprepared (in promise) Reply {url: "api / task / 8 / votes", body: "β΅β΅ β΅ β΅β΅β΅ β΅ β΅", headers: Object, status: 500, statusText: " Internal Server Error"...}