JonTan JonTan - 1 year ago 150
jQuery Question

Laravel Ajax Delete: 405 Error - Method Not Allowed

I know there are several posts about 405 Errors from using AJAX delete. However, none of the solutions from the posts I found worked for me.

I have a view with a table displaying all the machines from my database's Machine table. On each row there is a delete button to delete the machine like so:

<button class="btn btn-small btn-danger delete-machine"
type="button"
title="Delete Machine"
machine-id="{{ $value->machineId }}">
<span class="glyphicon glyphicon-trash"></span>
</button>


On button click, the following javascript executes which calls the destroy method in the controller to delete the machine from the database:

$(document).on('click', ".delete-machine", function() {
let button = $(this);
let id = $(this).attr('machine-id');
let tr = $(this).closest('tr');
let didConfirm = confirm("Are you sure you want to permanently delete this machine?");

if (didConfirm) {
$.ajax({
type: 'DELETE',
url: 'machines/' + id,
data: {
'_token' : $('input[name="_token"]').val(),
'id' : id
},
success: function(response) {
if (response.didSucceed) {
tr.remove();

let flashMessage = '<div class="alert alert-success alert-block"><button type="button" class="close" data-dismiss="alert">×</button><strong>'
+ response.message +
'</strong></div>';
$('#flash-message').append(flashMessage);
} else {
let flashMessage = '<div class="alert alert-error alert-block"><button type="button" class="close" data-dismiss="alert">×</button><strong>'
+ response.message +
'</strong></div>';
$('#flash-message').append(flashMessage);
}
},
error: function (response) {
console.log('Error:', response);
}
});
}
});


My controller is a resource controller. Here is the route:

Route::resource('machines', 'Machine\MachineController');


Here is the destroy method from the controller being called. It first deletes all the rows referencing the machine from a user subscription table. Then, it deletes the machine:

public function destroy($id)
{
$userMachineSubscriptions = UserMachineSubscription::where('machine_id', $id)->get();

foreach($userMachineSubscriptions as $userMachineSubscription) {
$userMachineSubscription->delete();
}

$userMachineSubscriptions = UserMachineSubscription::where('machine_id', $id)->count();

if ($userMachineSubscriptions <= 0) {
$machine = Machine::find($id);

if ($machine->delete()) {
$message = 'Machine "' . $machine['name'] . '" successfully deleted!';
return response()->json(['didSucceed' => 'true', 'message' => $message]);
} else {
$message = 'Machine "' . $machine['name'] . '" was not deleted.';
return response()->json(['didSucceed' => 'false', 'message' => $message]);
}
} else {
$message = 'Error performing cascading delete on user subscriptions. Machine was not deleted.';
return response()->json(['didSucceed' => 'false', 'message' => $message]);
}
}


When I run php artisan route:list, I see my route:

Method: DELETE
URI: machines/{machine}
Middleware: web, auth
Name: machines.destroy
Action: App\Http\Controllers\Machine\[email protected]


What am I doing wrong? Using Laravel 5.4.

...

Also, on a side note, I am new to web-development so if anyone sees anything in my code that can be improved someway, I am open to learning :) For example, I kind of dislike my method of showing a flash message on success. I do this for several ajax requests and wish I could just do session::flash or something instead of appending the html to a div in my master blade layout. However, I can't seem to find a better way to do it.

UDPATE: Solved. Just needed to clear the route cache. :(

Answer Source
php artisan route:list

See, If the DELETE request you are trying to send is allowed in the routes or not. You can also try to route:clear. to clear the route cache.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download