Mover Mover - 2 months ago 15
PHP Question

Laravel & VueJS Error: Call to a member function delete() on null; Internal Server Error 500

I am adding a list to a view using post request, then I append buttons to the list so that I can edit or delete the list using a vuejs but this only works if I refresh the page. If I try deleting or editing before I refresh the page I get an

Internal Server Error 500
and the following error in my log file:

local.ERROR: Symfony\Component\Debug\Exception\FatalThrowableError: Call to a member function delete() on null in /home/vagrant/Code/Eventer/app/Http/Controllers/EventController.php:93


Here is my AddTodo.vue file for adding to the list

<script>
export default {
props: ['newtodo'],

data() {
return {
todo: {id: null, name: '', completed: false}
}
},

methods: {
addTodo() {
var postData = {name: this.todo.name}
this.$http.post('/todo', postData).then((response)=>{
console.log(response);
}).catch((response)=>{
console.log('Error', response);
}
);
this.newtodo = this.todo;
this.todo = {id: null, name: '', completed: false};
}
}
}
</script>


<template>
<form v-on:submit.prevent="addTodo()">
<div class="form-group">
<input type="text" class="form-control" placeholder="Enter new Todo" v-model="todo.name">
</div>

<div class="form-group">
<button class="btn btn-success">Add</button>
</div>
</form>
</template>


Here is my ShowTodo.vue file for showing the list

<script>
export default {


props: ['todos'],


methods: {
todoCompleted(todo) {
var postData = {id: todo.id};
this.$http.post('/edit', postData).then((response)=> {


if (response.status == 200) {
todo.completed = !todo.completed;
}


}).catch((response)=> {

console.log('Error', response);
});

},

todoDelete(todo){

var postData = {id: todo.id};

this.$http.post('/delete', postData).then((response)=> {


if (response.status == 200) {

this.todos.$remove(todo);

}


}).catch((response)=> {

console.log('Error', response);
});

}
}
}
</script>

<template>
<div>
<ul class="list-group nomargin">
<li
v-for="todo in todos"
class="list-group-item"
v-bind:class="{ 'completed' : todo.completed }">
{{todo.name}}
<button class="btn btn-xs pull-right btn-danger margin-10" v-on:click="todoDelete(todo)">
<i class=" fa fa-trash"></i>
</button>
<button class="btn btn-xs pull-right margin-right-10"
v-bind:class="{'btn-success' : todo.completed, 'btn-warning' : !todo.completed}"
v-on:click="todoCompleted(todo)">{{todo.completed ? 'Completed' : 'Pending'}}
</button>
</li>
</ul>
</div>
</template>


<style lang="stylus">
.nomargin {
margin-left: 0px !important;
margin-right: 0px !important;
}

.margin-10 {
margin-left: 10px;
}

</style>


And here is my main.js file

import Vue from 'vue';
import VueResource from 'vue-resource';
import AddTodo from './components/AddTodo.vue';
import ShowTodo from './components/ShowTodo.vue';
Vue.use(VueResource);
Vue.component('show-todo', ShowTodo);
Vue.component('add-todo', AddTodo);

Vue.http.headers.common['X-CSRF-TOKEN'] = document.querySelector("meta[name=csrf-token]").getAttribute('content');


new Vue({
el: '#app-layout',

created()
{
this.$http.get('api/todos').then((response)=> {
console.log(response);
if(response.status==200){
this.todos =response.data;
}
});
} ,

data: {

newTodo: {},
todos: []
},

watch: {
newTodo(newval, oldval) {

this.todos.push(newval);
}
}
});


Note: I have also added a csrf-token meta to an app view file from which a welcomepage extends.

EDIT: Here is the delete controller on the following route
Route::post('test.app/delete', 'EventController@destroy');
below

public function destroy(Request $request)
{
$id = $request->input('id');
$event = Event::where('id', $id)->first();
$event->delete(); // This is line 93 where I get the below error
return response($event, 200);
}


This is the error I am getting on line 93 shown by the comment above

local.ERROR: Symfony\Component\Debug\Exception\FatalThrowableError: Call to a member function delete() on null in /home/vagrant/Code/Eventer/app/Http/Controllers/EventController.php:93

Answer

The problem was I was not assigning response data to my newtodo and clearing the todo to blank in the appropriate line my AddTodo vue file. It should be like this:

<script>
export default {
props: ['newtodo'],

data() {
    return {
        todo: {id: null, name: '', completed: false}
    }
},

methods: {
    addTodo() {
        var postData = {name: this.todo.name}
        this.$http.post('/todo', postData).then((response)=>{
            console.log(response);
            this.newtodo = response.data;
            this.todo = {id: null, title: '', completed: false};

        }).catch((response)=>{
            console.log('Error', response);
                }
        );
        ;
    }
 }
}

</script>
//Form goes here