Well, you probably do two requests somehow... Axios is not suddenly firing two calls. Can you show more of your code?
Axios sends two requests
Hi everyone,
I've got this code:
axios.delete('/notes/' + this.note.id + '/favorite');
But if I inspect my network tab, I see these two requests:
delete: http://notes.local/notes/4/favorite
delete: http://notes.local/notes/4
So, my note will be deleted too. What can I do about this?
Thank you! Jeroen
Note: by the favorite post request I do have the same problem, but then I get a 404 error, so it's not a problem.
@bobbybouwmann yes, of course!
Here's my full FavoriteButtonComponent:
<template>
<div>
<button v-if="favorited" @click="unfavorite"><i class="fas fa-star"></i></button>
<button v-else @click="favorite"><i class="far fa-star"></i></button>
</div>
</template>
<script>
export default {
props: [
'note'
],
data() {
return {
favorited: false
}
},
methods: {
favorite() {
this.favorited = true;
axios.post('/notes/' + this.note.id + '/favorite');
},
unfavorite() {
this.favorited = false;
axios.delete('/notes/' + this.note.id + '/favorite');
}
},
mounted() {
this.favorited = this.note.is_favorited;
}
}
</script>
This does look correct. I don't see a reason why it would fire two calls and especially not two different URLs.
Do you have more components that use this component? Can you show the component that uses this URL http://notes.local/notes/4?
@bobbybouwmann this is the only one, DeleteButtonComponent, but I do not see any reason why it would happen.
<template>
<div>
<button @click="deleteNote"><i class="fas fa-trash-alt"></i></button>
</div>
</template>
<script>
export default {
props: [
'id'
],
methods: {
deleteNote() {
axios.delete('/notes/' + this.id)
.then(function() {
this.$root.$emit('emptyNote');
this.$root.$emit('refresh');
}.bind(this));
}
}
}
</script>
@bobbybouwmann but if I remove that component I still have the same problem.
I honestly have no idea at this point
Check the naming in the code.
if you are buliding a SPA with vue-router , pay attention to the wildcard route model binding , don't use the same name , vue-router will transform request for example laravel route
post '/notes/{note}/favorate'
vue-router
path: '/notes/:note' , //this is vue router path , a get request
so , change laravel route name to notestest and try again
Hi @jlrdw how do you mean check the naming?
Hı @maverickchan I don't use Vue Routing, but Laravel Routing.
These are my routes:
Route::get('/', function () {
return view('welcome');
});
Route::get('/notes', 'NoteController@show');
Route::post('/notes', 'NoteController@store');
Route::patch('/notes/{note}', 'NoteController@update');
Route::delete('/notes/{note}', 'NoteController@destroy');
Route::post('/notes/{note}/favorite', 'NoteFavoritesController@store');
Route::delete('/notes/{note}/favorite', 'NoteFavoritesController@destroy');
Route::get('/api/notes', 'NoteController@index');
Route::get('/api/notes/{note}', 'NoteController@edit');
Auth::routes();
Route::get('/home', 'HomeController@index')->name('home');
Note: If I remove the axios delete request from the FavoriteButtonComponent, the note does not get deleted. So the problem is some where in that component.
these are in your web.php file right? what is in your api.php? did you change anything.
as far as i can tell you provide 2 conflict route
post and delete at the same route name rename delete
Route::delete('/notes/{note}/unfavorite','NoteFavoritesController@destroy');
Hi @maverickchan,
I do not use the api.php, because I don't know how it works.
You said you saw a conflicting route? Can you tell me more about that?
Thank you! Jeroen
Route::post('/notes/{note}/favorite', 'NoteFavoritesController@store');
Route::delete('/notes/{note}/favorite', 'NoteFavoritesController@destroy');
these 2 routes are the same change delete to unfavorite
Hi @maverickchan,
I changed it but it doesn't fix it, which makes sense actually, because Laravel makes difference between post and delete requests.
However, thanks for trying to help me!
npm run dev or watch again and give the browser a hard refresh check your other component again
Yes I did but it doesn't change...
@bobbybouwmann @jlrdw @maverickchan Does anyone know how to solve this?
@jeroenvanrensen Can you post your routes, controller, and component again? The code you have right now?
@bobbybouwmann sure here you have it.
FavoriteButtonComponent.vue
<template>
<div>
<button v-if="favorited" @click="unfavorite"><i class="fas fa-star"></i></button>
<button v-else @click="favorite"><i class="far fa-star"></i></button>
</div>
</template>
<script>
export default {
props: [
'note'
],
data() {
return {
favorited: false
}
},
methods: {
favorite() {
this.favorited = true;
axios.post('/notes/' + this.note.id + '/favorite');
this.$root.$emit('refresh');
},
unfavorite() {
this.favorited = false;
axios.delete('/notes/' + this.note.id + '/favorite');
this.$root.$emit('refresh');
}
},
mounted() {
this.favorited = this.note.is_favorited;
}
}
</script>
routes/web.php
<?php
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', function () {
return view('welcome');
});
Route::get('/notes', 'NoteController@show');
Route::post('/notes', 'NoteController@store');
Route::patch('/notes/{note}', 'NoteController@update');
Route::delete('/notes/{note}', 'NoteController@destroy');
Route::post('/notes/{note}/favorite', 'NoteFavoritesController@store');
Route::delete('/notes/{note}/favorite', 'NoteFavoritesController@destroy');
Route::get('/api/notes', 'NoteController@index');
Route::get('/api/notes/{note}', 'NoteController@edit');
Auth::routes();
Route::get('/home', 'HomeController@index')->name('home');
NoteController.php
<?php
namespace App\Http\Controllers;
use App\Note;
use Carbon\Carbon;
class NoteController extends Controller
{
/**
* Only authenticated users can use this controller
*
* @return void
*/
public function __construct()
{
$this->middleware('auth');
}
/**
* Returns all the notes of the authenticated user
*
* @return array
*/
public function index()
{
$notes = \App\Note::where('user_id', auth()->id());
if(request()->has('favorites')) {
$notes = $notes->where('is_favorited', true);
}
if(request()->has('trash')) {
$notes = $notes->onlyTrashed();
}
if(request()->has('query')) {
$notes = $notes->where('title', 'like', '%' . request('query') . '%');
}
$notes = $notes->orderBy('updated_at', 'desc')->get();
return $notes;
}
/**
* Returns an empty page
*
* @return view
*/
public function show()
{
$this->permanentlyDeleteNotes();
return view('notes.show');
}
/**
* Creates a new note
*
* @return void
*/
public function store()
{
$note = Note::create([
'title' => $this->setTitle(''),
'user_id' => auth()->id()
]);
return $note->id;
}
/**
* Returns the note in an edit form
*
* @param Note $note
*
* @return view
*/
public function edit(Note $note)
{
$this->authorize('update', $note);
if($note->trashed()) {
$note->restore();
}
return $note;
}
/**
* Saves the edited note
*
* @param Note $note
*
* @return void
*/
public function update(Note $note)
{
$this->authorize('update', $note);
$note->update([
'title' => $this->setTitle(request('body')),
'body' => request('body')
]);
}
/**
* Deletes a note
*
* @param Note $note
*
* @return void
*/
public function destroy(Note $note)
{
$this->authorize('update', $note);
$note->delete();
}
/**
* Generates a title based on the body
*
* @param string $body
*
* @return string
*/
protected function setTitle($body)
{
if($title = strtok($body, "\n")) {
return preg_replace('/^[ #]+/', '', $title);
}
return 'Untitled';
}
protected function permanentlyDeleteNotes()
{
Note::withTrashed()
->where('deleted_at', '<', Carbon::now()->subMonth())
->forceDelete();
}
}
in your controller , destroy () function , you authorize a 'update' instead of 'delete'
that could be the problem?
Hi @maverickchan,
It's working! Now Axios also sends a patch request, but that returns in a 404 error. So the client doesn't notice. It's not perfect, but it works!
Thank you very much! Jeroen
you can try my previous suggestion ,change delete route to /unfavorite
maybe you should see Jeffery's tutorial of Building a forum with TDD , i remember he has a favorite unfaoverite example, and pay attention to the controller
@bobbybouwmann @jlrdw @maverickchan
I finally found the problem
This is my controller code:
<?php
namespace App\Http\Controllers;
use App\Note;
class NoteFavoritesController extends Controller
{
/**
* Saves a favorite
*
* @param Note $note
*
* @return redirect
*/
public function store(Note $note)
{
$this->authorize('update', $note);
$note->favorite();
return redirect('/notes/' . $note->id);
}
/**
* Removes a favorite
*
* @param Note $note
*
* @return redirect
*/
public function destroy(Note $note)
{
$this->authorize('update', $note);
$note->unfavorite();
return redirect('/notes/' . $note->id);
}
}
But because of the redirects at the end it does not work. So if I remove them, it does work!
Aah yeah, that makes sense. You can't redirect to a note you just deleted. In your case, you should never return a redirect in an ajax request ;)
Please or to participate in this conversation.