Laravel and Vuejs axios delete gives no error but doesnt delete - laravel

I created a web route that must delete a contact based on a specific id and it looks like this:
Route::delete('/api/deleteContact/{id}', 'ContactController#destroy');
Then inside the controller, I have the following:
public function destroy($id)
{
// delete a contact by id
return response()->json(Contact::whereId($id), 200);
}
Inside one of my blade template files, I call the Vue component which displays the list of contacts:
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Name</th>
<th scope="col">Phone</th>
</tr>
</thead>
<tbody>
<tr v-for="contact in contacts">
<td> {{ contact.id }} </td>
<td> {{ contact.name }} </td>
<td> {{ contact.phone }} </td>
<td><button class="btn btn-secondary">Edit</button></td>
<td><button #click="deleteContact(contact.id)" class="btn btn-danger">Delete</button></td>
</tr>
</tbody>
</table>
The delete button calls the deleteContact method and received the contact id in question.
The method looks like this:
deleteContact(id){
axios.delete('/api/deleteContact/' + id)
.then(res => {
for(var i = 0; i < this.contacts.length; i++) {
if(this.contacts[i].id == id) {
this.contacts.splice(i, 1);
}
}
})
.catch(err => console.log(err));
}
When I click to delete, the promise(then) occurs, however, after refreshing the page, I noticed that nothing was deleted and I see no errors in the console.
How can I successfully delete the contact based on the id passed in the deleteContact function ?

You have to append delete at the end of query like this:
public function destroy($id)
{
// delete a contact by id
return response()->json(Contact::where('id',$id)->delete(), 200);
}

Related

data not displaying in table in vuejs

i have created vue file to display data in frontend. but i'm unable to print 2 tables on same page at same time. only table 2 is displaying data , in first table it shows data for 2 seconds and than disappears. what i'm doing wrong? please help. i am super new in vuejs and have not much knowledge.
here is my index.vue file,
Table 1
<tbody>
<tr
v-show="items && items.length"
v-for="(data, i) in items"
:key="i">
<td></td>
<td></td>
</tr>
and this is function code,
async fetchData1() {
this.$store.state.operations.loading = true;
let currentPage = this.pagination ? this.pagination.current_page : 1;
await this.$store.dispatch("operations/fetchData", {
path: "/api/calldata?page=",
currentPage: currentPage + "&perPage=" + this.perPage,
});
table 2
<tbody>
<tr
v-show="items && items.length"
v-for="(data, i) in items"
:key="i">
<td></td>
<td></td>
</tr>
and here is the function for table 2
async fetchData2() {
this.Loading2 = true
let currentPage = this.Pagination2 ? this.Pagination2.current_page : 1;
await this.$store.dispatch("operations/fetchData", {
path: "/api/datacall/data2?page=",
currentPage: currentPage + "&perPage=" + this.perPage,
});
this.Loading2 = false;
and this are the controller functions
public function index(Request $request)
{
return DataResource::collection(Datamodl::with('user')->where('type',1)->latest()->paginate($request->perPage));
}
public function index2(Request $request)
{
return DataResource::collection(Datamodl::with('user')->where('type',0)->latest()->paginate($request->perPage));
}
And Route ,
Route::get('/calldata/data2', [DataController::class, 'index2']);
Route::apiResource('calldata', DataController::class);
Observation : You are updating same variable which is items for both the tables. Hence, it is overriding the latest items with the old items array.
Solution : Here is the implementation as per my comment.
new Vue({
el: '#app',
data: {
table1Items: null,
table2Items: null
},
mounted() {
this.fetchData1();
this.fetchData2();
},
methods: {
fetchData1() {
this.table1Items = [{
id: 1,
name: 'table 1 alpha'
}, {
id: 2,
name: 'table 1 beta'
}]
},
fetchData2() {
this.table2Items = [{
id: 1,
name: 'table 2 alpha'
}, {
id: 2,
name: 'table 2 beta'
}]
}
}
})
table, th, td {
border: 1px solid black;
margin: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<table>
<thead>
<th>ID</th>
<th>Name</th>
</thead>
<tbody>
<tr v-show="table1Items" v-for="(data, i) in table1Items" :key="i">
<td>{{ data.id }}</td>
<td>{{ data.name }}</td>
</tr>
</tbody>
</table>
<table>
<thead>
<th>ID</th>
<th>Name</th>
</thead>
<tbody>
<tr v-show="table2Items" v-for="(data, i) in table2Items" :key="i">
<td>{{ data.id }}</td>
<td>{{ data.name }}</td>
</tr>
</tbody>
</table>
</div>
you are using same property which is items for both. so second request will changed first items. so in both table same data will visible. you have to store in different state property for different data rendering.
solution :
make another action fetchData2.
call another mutation setItems2. add state propery item2: []. and setItems2 value from this mutation.
render second table like this.
<tr
v-show="items2.length"
v-for="(data, i) in items2"
:key="i">
<td></td>
<td></td>
</tr>
For code quailty:
give proper and related variable name . don't use items1 and items2 like that.
never used v-if/v-show and v-for in same element.for more info
use template first in this senerio.
use the item's unique id instead of the index in the key.
if you take the items default value as [], instead of null, then you only required to check items.length instead of items && items.length. so always use list default value []
if both requests are not dependent on each other then you should use Promise.all() for fetching data concurrently. which saved tremendous time and also in this case you don't require two loading property.

Cannot update multiple rows with same value in Laravel Vue Axios

can't update multiple row with a single value passing from vue js.I want to add pay value with database column advance with previous value in database.And also how to pass substraction of patientInfo.due-form.pay using axios.
Vuejs template:
<form #submit.prevent="updatePatientPayment">
<table class="table">
<tfoot>
<tr>
<td colspan="5" class="text-right">Total</td>
<td class="text-right">{{patientInfo.total}}</td>
</tr>
<tr>
<td colspan="5" class="text-right">Advance Paid</td>
<td class="text-right">{{patientInfo.advance}}</td>
</tr>
<tr>
<td colspan="5" class="text-right">Due</td>
<td class="text-right" >{{patientInfo.due}}</td>
</tr>
<tr>
<td colspan="5" class="text-right">Payable</td>
<input class="form-control text-right" type="number" v-model="form.pay"/>
</tr>
<tr>
<td colspan="5" class="text-right">New Due</td>
<td class="text-right">{{patientInfo.due-form.pay}}</td>
</tr>
</tfoot>
</table>
<b-button type="submit" variant="success">Submit</b-button>
</form>
Vuejs Script:
<script>
export default {
data(){
return{
id:this.$route.params.id,
patient:[],
patientInfo:{},
form:{
pay:0,
}
}
},
methods:{
updatePatientPayment() {
this.$http.post('http://127.0.0.1:8000/api/updatePatientPayment/' + this.id,this.form)
.then(()=>{
self.message = 'Data is entered';
})
},
}
</script>
Laravel Controller:
public function updatePatientPayment($id, Request $request)
{
$updatePatientPayment = Patient::find([$id]);
foreach($updatePatientPayment as $p){
$p->advance = $p->update([$advance + $request->pay]);
$p->save();
}
return response()->json(['successfully updated']);
}
As already mentioned you don't need an array here if you only update one Patient.
public function updatePatientPayment($id, Request $request)
{
// 1. Get the patient you want to update
// Do not wrap $id in [] if you only need to find one entity
$patient = Patient::find($id);
// 2. Change the value of the patient
// Do not use update when you assign the value to the model
$patient->advance += $request->pay;
// 3. Save the change
$patient->save();
// 4. Respond
return response()->json(['successfully updated']);
}
Alternatively, you can also use update if you want to, but be aware that your advance field must be defined as fillable to do so.
public function updatePatientPayment($id, Request $request)
{
// 1. Get the patient you want to update
// Do not wrap $id in [] if you only need to find one entity
$patient = Patient::find($id);
// 2. Update directly
$patient->update(['advance' => $patient->advance + $request->pay]);
// 3. Respond
return response()->json(['successfully updated']);
}
update will already save your change.
In your code $advance is not defined. You cannot access the existing column as you did.

laravel vue send array to backend

I want to send array of id's to backend with one button from vuejs table but i get error 500.
Logic
Check the check boxes
Collect the id's
Send id's to back-end when click on button
update the view
Code
template
<table class="table table-dark table-hover table-bordered table-striped">
<thead>
<tr>
<th class="text-center" width="50">
//the button
<button class="btn btn-outline-danger" #click="withdraw(index)">Withdraw</button>
</th>
<th class="text-center" width="50">#</th>
<th class="text-center">Amount</th>
</tr>
</thead>
<tbody>
<tr v-for="(income,index) in incomes" v-bind:key="index">
<td class="text-center">
//check box input
<input v-if="income.withdraw == '0'" type="checkbox" :id="income.id" :value="income.amount" v-model="checkedNumbers">
</td>
<td class="text-center">{{index+1}}</td>
<td class="text-center">Rp. {{formatPrice(income.amount)}}</td>
</tr>
<tr>
<td colspan="2"></td>
<td>
<span>Withdraw for today, Sum: <br> Rp. {{ formatPrice(sum) }}</span>
</td>
</tr>
</tbody>
</table>
script
export default {
data() {
return {
incomes: [],
checkedNumbers: [],
}
},
computed: {
sum() {
return this.checkedNumbers.reduce(function (a, b) {
return parseInt(a) + parseInt(b);
}, 0);
}
},
methods: {
withdraw(index) {
let checkedids = this.incomes[index]
axios.post(`/api/withdrawbutton/`+checkedids).then(response => {
this.income[index].withdraw = '1'
this.$forceUpdate()
});
}
}
}
route
Route::post('withdrawbutton/{id}', 'IncomeController#withdrawbutton');
controller
public function withdrawbutton($id)
{
$dowithdraw = Income::where('id', $id)->get();
$dowithdraw->withdraw = '1';
$dowithdraw->save();
return response()->json($dowithdraw,200);
}
Any idea where is my mistake and how to fix it?
......................................................................................................................
Don't send the list as a GET parameter, send it as a POST:
let params = {}
params.ids = this.checkedNumbers
axios.post(`/api/withdrawbutton/`, params)
.then(response => {
this.income[index].withdraw = '1'
this.$forceUpdate()
});
Controller
public function withdrawbutton(Request $request)
{
$dowithdraws = Income::whereIn('id', $request->input('ids', []));
$dowithdraws->update(['withdraw' => '1']);
return response()->json($dowithdraws->get(), 200);
}
Route
Route::post('withdrawbutton/', 'IncomeController#withdrawbutton');
And I don't think you need to update anything in the front because you already have them checked (if you want to keep them checked)

Checkbox doesn't save true value

I'm using Laravel 5.6 and Vuejs 2.
If I click on my checkbox and make the value true it's supposed to save a 1 in the database and if I click my checkbox and make the value false it saves a 0.
The problem I'm having is that if I click my checkbox and make it true, it doesn't save the correct value, no changes is made to the database and I don't get any errors. If I click on my checkbox and make it false, it saves the 0 correctly.
I did notice that even when my value is supposed to be true, I do get a false when I dd($category->has('active')
I'm not sure where I'm going wrong or how to fix it.
My vue file
<template>
<div class="card-body">
<table class="table">
<thead class="thead-dark">
<tr>
<th scope="col">Active</th>
<th scope="col">Title</th>
<th scope="col">Edit</th>
<th scope="col">Delete</th>
</tr>
</thead>
<tbody>
<tr v-for="(category, index) in categoriesNew" >
<td>
<label>checkbox 1</label>
<input name="active" type="checkbox" v-model="category.active" #click="checkboxToggle(category.id)">
</td>
<td>
{{ category.title }}
</td>
</tr>
</tbody>
</table>
</div>
</template>
<script>
export default {
props: ['categories'],
data(){
return {
categoriesNew: this.categories
}
},
methods: {
checkboxToggle(id){
console.log(id);
axios.put('/admin/category/active/'+id, {
categories: this.categoriesNew
}).then((response) => {
//Create success flash message
})
},
},
mounted() {
console.log('Component mounted.')
}
}
</script>
my routes
Route::put('admin/products/updateAll', 'Admin\ProductsController#updateAll')->name('admin.products.updateAll');
Route::put('admin/category/active/{id}', 'Admin\CategoryController#makeActive')->name('admin.category.active');
Route::resource('admin/category', 'Admin\CategoryController');
Route::resource('admin/products', 'Admin\ProductsController');
my CategoryController#makeActive
public function makeActive(Request $request, $id)
{
$category = Category::findOrFail($id);
if($request->has('active'))
{
$category->active = 1;
}else{
$category->active = 0;
}
$category->save();
}
I hope I made sense. If there is anything that isn't clear or if you need me to provide more info, please let me know
Try changing this line
categories: this.categoriesNew
to
categories: category.active
and add a data prop at the top called category.active: ''
I've managed to get it to work. This is what I did.
vue file
<template>
<div class="card-body">
<table class="table">
<thead class="thead-dark">
<tr>
<th scope="col">Active</th>
<th scope="col">Title</th>
<th scope="col">Edit</th>
<th scope="col">Delete</th>
</tr>
</thead>
<tbody>
<tr v-for="(category, index) in categories" >
<td>
<label>checkbox 1</label>
<input type="checkbox" v-model="category.active" #click="checkboxToggle(category)">
</td>
<td>
{{ category.title }}
</td>
</tr>
</tbody>
</table>
</div>
</template>
<script>
export default {
props: ['attributes'],
data(){
return {
categories: this.attributes,
}
},
methods: {
checkboxToggle (category) {
axios.put(`/admin/category/${category.id}/active`, {
active: !category.active
}).then((response) => {
console.log(response)
})
}
},
mounted() {
console.log('Component mounted.')
}
}
</script>
my routes
Route::put('admin/category/{category}/active', 'Admin\CategoryController#makeActive')->name('admin.category.active');
and my CategoryController#makeActive
public function makeActive(Request $request, $id)
{
$category = Category::findOrFail($id);
if(request('active') === true)
{
$category->active = 1;
}else{
$category->active = 0;
}
$category->save();
}

how to get data from laravel5.5?

I am using Laravel 5.5 and I want to view my data in database from my view page (home.blade.php)
<table>
<tbody>
#foreach($home as $key => $data)
<tr>
<th>{{$data->created_at}}</th>
<th>{{$data->category}}</th>
<th>{{$data->reportitle}}</th>
<th>{{$data->reportdetails}}</th>
<th>{{$data->seenstat}}</th>
<th>{{$data->actionstat}}</th>
<th>{{$data->donestat}}</th>
</tr>
#endforeach
</tbody>
</table>
In my home.blade.php I have an empty table and I want to show data from database fyp:
Route::get('home', function () {
$fyp = DB::table('reports')->get();
return view('home', ['fyp' => $fyp]);
});
This must work (as #Nazmul said):
#foreach($fyp as $data)
<tr>
<th>{{$data->created_at}}</th>
<th>{{$data->category}}</th>
<th>{{$data->reportitle}}</th>
<th>{{$data->reportdetails}}</th>
<th>{{$data->seenstat}}</th>
<th>{{$data->actionstat}}</th>
<th>{{$data->donestat}}</th>
</tr>
#endforeach
just follow the code
Route::get('home', function () {
$home = DB::table('reports')->get();
return view('home', compact('home'));
});
After in your view page
<table>
<tbody>
#foreach($home as $key => $data)
<tr>
<th>{{$data->created_at}}</th>
<th>{{$data->category}}</th>
<th>{{$data->reportitle}}</th>
<th>{{$data->reportdetails}}</th>
<th>{{$data->seenstat}}</th>
<th>{{$data->actionstat}}</th>
<th>{{$data->donestat}}</th>
</tr>
#endforeach
</tbody>
</table>
I hope this will help you.

Resources