0

I'm pretty new to Laravel, I've been trying to pass parameters to the destroy() action in my controller with Ajax, the action runs as the pictures data gets removed both from the database and the picture from storage as well, however it gives back 405 error in the console for some reason. I've tried multiple solutions posted here, but none has worked unfortunately. The destroy() action works if I'm using it purely with PHP, but I'm trying to learn a bit of Ajax as well, also I'm doing it this way because I want to do it like there are multiple photos on the site at once, and each one has its own delete button, and I want to delete the photo based on which delete button has been pressed.

It says in the response headers that only GET, HEAD allowed.

Any help would be greatly appreciated, and thank you all in advance!

Routes

Route::get('/photos/create/{albumId}', [PhotosController::class, 'create'])->name('photo-create');
Route::post('/photos/store', [PhotosController::class, 'store'])->name('photo-store');
Route::get('/photos/{id}', [PhotosController::class, 'show'])->name('photo-show');
Route::delete('/photos/{id}', [PhotosController::class, 'destroy'])->name('photo-destroy');

Controller

 public function destroy($id)
{
    $photo = Photo::find($id);

    if (Storage::delete('/public/albums/' . $photo->album_id . '/' . $photo->photo ))
    {
        $photo->delete();

        return redirect('/')->with('success', 'Photo deleted successfully');
    }
}

Ajax

$(document).on('click', '.deletePhoto', function(e) {

        var photo = $(this).val();

        $('#deletePhotoId').val(photo);
        $('#photoDelete').modal('show');
    });


    $(document).on('click', '.confirmDelete', function(e) {

        var photo = $('#deletePhotoId').val();

        $.ajax({

            type: "DELETE",
            url: "/photos/"+photo,
            data: {
                _token: '{{ csrf_token() }}',
            },

            /* success: function(response){
                alert(response);
            },
            error: function(response) {
                alert('Error' + response); 
            } */
        })


    });

Also if I have added the csrf as in the Laravel documentation like this:

$.ajaxSetup({
    headers: {
        'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
    }
});

Then it gave me 419 error no matter where I have placed it.

Here's the error

XHRDELETEhttp://photo-project.test/
[HTTP/1.0 405 Method Not Allowed 61ms]

    
DELETE
    http://photo-project.test/
Status405
Method Not Allowed
VersionHTTP/1.0
Transferred8.43 kB (8.19 kB size)
Referrer Policystrict-origin-when-cross-origin
        
    Allow
        GET, HEAD
    Cache-Control
        no-cache, private
    Connection
        close
    Content-Type
        application/json
    Date
        Sat, 03 Jul 2021 20:21:15 GMT
    Server
        Apache/2.4.46 (Win64) PHP/7.3.21
    X-Powered-By
        PHP/7.3.21

    Accept
        */*
    Accept-Encoding
        gzip, deflate
    Accept-Language
        en-GB,en;q=0.5
    Connection
        keep-alive
    Content-Length
        47
    Content-Type
        application/x-www-form-urlencoded; charset=UTF-8
    Cookie
        XSRF-TOKEN=eyJpdiI6IlR0bitkaitPMFhhWEdnQ1ZqL1VpTXc9PSIsInZhbHVlIjoibVREOG9JRGpOQjBqZG40QU9vWVJsS2xtT2J3OXZJK3ZjVzNzZHNKNWdQakowK1lMZ1o0RStSQWFzTVFYZ1R5cFEvNjQ2bm9ZNklYbW8xcW54ZVlzOG9sVXJXN1Z3dmU0Lys0UXRWNWZLY29Femxjb2EvS09qM0hzbm9SSndOYXIiLCJtYWMiOiI2MWJlOTc3YWFhY2NkY2VhZGM5YWZhYmE0MjcyYTc5MmRiNmQwMjU0ZmFlZmMxYzEzNTExMGU4ZjlhMTY3OTYwIn0%3D; laravel_session=eyJpdiI6IldCNU9MSHRGbnNJRlEvWDBrMmZzSmc9PSIsInZhbHVlIjoidzhoc0VFajBhZXk2dkFSa2VmNkU2UmVReVZaOFFUeGJPam1pOXI3T3gvR0FFM3crd21SODI1ZWFJZk44UThDM0VjNFdsL2V6bzNvcHk0NG9vQlpoTEtIRlNQOStxaDlvVFUvS01iOEJIUDJzODFyck11ckpZRTRzMHhVYXhHZlYiLCJtYWMiOiI5NGJmMTBlMDhlOWU0OTU4ZDkyZWRhMzlhYzIwNzFkOTAzZWI3M2RjOTEzNzI5NTYyOWFkZWIyOWMyM2E3MmM2In0%3D
    Host
        photo-project.test
    Origin
        http://photo-project.test
    Referer
        http://photo-project.test/albums/12
    User-Agent
        Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:89.0) Gecko/20100101 Firefox/89.0
    X-Requested-With
        XMLHttpRequest

Thank you again if you can help me in any measure as I'm kind of stuck here unfortunately.

mudriroli
  • 3
  • 2

2 Answers2

1

Double-check that your photo JS variable actually has a value. If it's null for some reason, then the route being constructed would end up being the 'index' one, "/photos/", which of course does not have a DELETE http method associated with it.

Check your browser Network history to be sure. You'll see the route that it's attempting to hit, and can also double-check that against the results of php artisan route:list.

kmuenkel
  • 2,659
  • 1
  • 19
  • 20
  • Yes I've checked it before, the photo variable receives the photos id correctly and the action actually deletes it as well as, but in the console 405 shows for some reason, also it does not redirects as the action should. I press the delete button in the modal, then the error appears in the console but it does not redirects. However when I refresh the page then it disappears so the action seems to run. – mudriroli Jul 02 '21 at 15:49
  • It's not going to redirect since you are making the request through AJAX. Since you are doing AJAX here, you need to handle the redirect on response done/fail. Can you share the error you receive in the console? – Sakibul Alam Jul 03 '21 at 17:21
  • Thank you for the answer! I've had suspicions that the redirect wont execute due to Ajax but now I know for certain so thank you. I've attached the complete error message that the browser's console gives to the post. – mudriroli Jul 03 '21 at 20:33
0
public function destroy(Request $request, $id){
    $photo = Photo::find($id);
    if (Storage::delete('/public/albums/' . $photo->album_id . '/' .$photo->photo )){
        $photo->delete();
        
        //if request is via ajax 
        if($request->ajax()){
            return response()->json(['status'=>true,'message'=>'Photo Deleted Successfully']);
        }
        //otherwise redirect 
        return redirect('/')->with('success', 'Photo deleted  successfully');
    }
}

On Ajax Side

$(document).on('click', '.deletePhoto', function(e) {

        var photo = $(this).val();

        $('#deletePhotoId').val(photo);
        $('#photoDelete').modal('show');
    });


    $(document).on('click', '.confirmDelete', function(e) {

        var photo = $('#deletePhotoId').val();
        $.ajax({
            type: "DELETE",
            url: "/photos/"+photo,
            data: {
                _token: '{{ csrf_token() }}',
            },
            dataType:'JSON',
            cache:false,
             success: function(response){
                if(response.status){
                    console.log('Action Successfull....');
                    console.log('Response from server : ', response.message)
                }
            },
            error: function(response) {
                alert('Error' + response);
            }
        })
    });

Just check the request type while returning response from server, If it is ajax then return the response data otherwise redirect to the page.

Muhammad Atif Akram
  • 1,204
  • 1
  • 4
  • 12
  • Thank you so much! This worked! I guess the issue was that the action did not give back anything to the Ajax. Thank you very much again! – mudriroli Jul 05 '21 at 18:53