skip to Main Content

Hello Good Day to anyone who would see this, I am new to Laravel and currently having a minor problem that for some reason every time I delete, it would show the 405 (Method Not Allowed) in the console. The reason I considered it a minor problem since it works anyways when I refresh it.

I’m sorry if I’m bad at explaining but here’s some screenshots to hopefully clarify the situation

Error Message Triggered when I press Delete

Console Log

But note that when I refresh it actually deletes that record…

I would post what I think are the relevant codes here :<

Controller:

<?php

namespace AppHttpControllers;

use AppModelsWaste;
use IlluminateHttpRequest;

class WasteController extends Controller
{
    public function index()
    {
        $waste = Waste::all();
        return view('wastes.index', compact('waste'));
    }

    public function create()
    {
        return view('wastes.create');
    }    

    public function store(Request $request)
    {
        // Validate the request
        $request->validate([
            'WasteID' => 'required|unique:wastes', 
            'WasteName' => 'required',
            
        ]);

        // Create
        Waste::create($request->all());

        return redirect()->route('wastes.index')->with('success', 'Waste record created successfully!');
    }

    public function show($id)
    {
        $waste = Waste::findOrFail($id);
        return view('wastes.show', compact('waste'));
    }

    public function edit($id)
    {
        $waste = Waste::findOrFail($id);
        return view('wastes.edit', compact('waste'));
    }

    public function update(Request $request, $id)
    {
        // Validate
        $request->validate([
            'WasteID' => 'required|unique:wastes,WasteID,' . $id, 
            'WasteName' => 'required',
            
        ]);

        // Update
        $waste = Waste::findOrFail($id);
        $waste->update($request->all());

        return redirect()->route('wastes.index')->with('success', 'Waste record updated successfully!');
    }

    public function destroy($id)
    {
        $waste = Waste::findOrFail($id);
        $waste->delete();

        return redirect()->route('wastes.index')->with('success', 'Waste record deleted successfully!');
    }
}

Route:

use AppHttpControllersWasteController;

Route::get('/wastes', [WasteController::class, 'index'])->name('wastes.index');
Route::get('/wastes/create', [WasteController::class, 'create'])->name('wastes.create');
Route::resource('wastes', WasteController::class);
Route::delete('/wastes/delete-selected', [WasteController::class, 'deleteSelected'])->name('wastes.deleteSelected');
Route::delete('/wastes/{waste}', [WasteController::class, 'destroy'])->name('wastes.destroy');

View using it:

@extends('layouts.app')

@section('content')
    <h1>Waste Records</h1>

    @if(session('success'))
        <div class="alert alert-success">
            {{ session('success') }}
        </div>
    @endif

    <div class="mb-3">
        <a href="{{ route('wastes.create') }}" class="btn btn-primary">Create New Waste Record</a>
        <button class="btn btn-danger" onclick="deleteSelected()">Delete Selected</button>
    </div>

    <table class="table" id="wasteTable">
    <thead>
            <tr>
                <th data-sort="WasteID">Select</th>
                <th data-sort="WasteID">Waste ID</th>
                <th data-sort="WasteName">Waste Name</th>
                <th data-sort="WasteType">Waste Type</th>
                <th data-sort="TimeCollected">Time Collected</th>
                <th data-sort="MassCollected">Mass Collected</th>
                <th data-sort="AreaCollected">Area Collected</th>
                <th data-sort="DisposalLocation">Disposal Location</th>
                <th data-sort="WasteCategory">Waste Category</th>
                <th>Other Description</th>
                <th>Remarks</th>
                <th>Actions</th>
            </tr>
        </thead>
        <tbody>
            @forelse($waste as $record)
                <tr>
                    <td><input type="checkbox" name="selected[]" value="{{ $record->id }}"></td>
                    <td>{{ $record->WasteID }}</td>
                    <td contenteditable="false" data-id="{{ $record->id }}" data-field="WasteName" class="editable">{{ $record->WasteName }}</td>
                    <td>{{ $record->WasteType }}</td>
                    <td>{{ $record->TimeCollected }}</td>
                    <td>{{ $record->MassCollected }} kg</td>
                    <td>{{ $record->AreaCollected }}</td>
                    <td>{{ $record->DisposalLocation }}</td>
                    <td>{{ $record->WasteCategory }}</td>
                    <td>{{ $record->OtherDescription }}</td>
                    <td>
                        @if($record->Solid) Solid, @endif
                        @if($record->Liquid) Liquid, @endif
                        @if($record->Biodegradable) Biodegradable, @endif
                        @if($record->NonBiodegradable) Non-Biodegradable, @endif
                        @if($record->Recyclable) Recyclable, @endif
                        @if($record->Hazardous) Hazardous, @endif
                        @if($record->Corrosive) Corrosive, @endif
                        @if($record->Ignitable) Ignitable, @endif
                        @if($record->Reactive) Reactive, @endif
                        @if($record->Toxic) Toxic, @endif
                    </td>
                    <td>
                        <a href="{{ route('wastes.show', $record->id) }}" class="btn btn-info btn-sm">View</a>
                        <a href="{{ route('wastes.edit', $record->id) }}" class="btn btn-warning btn-sm">Edit</a>
                        <button class="btn btn-danger btn-sm" onclick="deleteRecord({{ $record->id }})">Delete</button>
                    </td>
                </tr>
            @empty
                <tr>
                    <td colspan="12">No waste records found.</td>
                </tr>
            @endforelse
        </tbody>
    </table>

    {{-- Scripts Area --}}
    <script src="{{ asset('jquery-3.7.1.js') }}"></script>
    <script>
         var sortOrder = {};

         
        $('table th').on('click', function() {
            var column = $(this).data('sort');
            if (!sortOrder[column]) {
                sortOrder[column] = 'asc';
            } else {
                sortOrder[column] = sortOrder[column] === 'asc' ? 'desc' : 'asc';
            }

            sortTable(column, sortOrder[column]);
        });

        
        function sortTable(column, order) {
            var rows = $('table tbody tr').get();

            rows.sort(function(a, b) {
                var keyA = $(a).children('td').eq(getColumnIndex(column)).text();
                var keyB = $(b).children('td').eq(getColumnIndex(column)).text();

                if (order === 'asc') {
                    return (keyA > keyB) ? 1 : -1;
                } else {
                    return (keyA < keyB) ? 1 : -1;
                }
            });

            $.each(rows, function(index, row) {
                $('table tbody').append(row);
            });
        }

        
        function getColumnIndex(columnName) {
            var index = -1;
            $('table th').each(function(i) {
                if ($(this).data('sort') === columnName) {
                    index = i;
                    return false;
                }
            });
            return index;
        }

        
        function sortTable(column, order) {
            var rows = $('table tbody tr').get();

            rows.sort(function(a, b) {
                var keyA = $(a).children('td').eq(getColumnIndex(column)).text();
                var keyB = $(b).children('td').eq(getColumnIndex(column)).text();

                if (order === 'asc') {
                    return (keyA > keyB) ? 1 : -1;
                } else {
                    return (keyA < keyB) ? 1 : -1;
                }
            });

            $.each(rows, function(index, row) {
                $('table tbody').append(row);
            });
        }

        
        function getColumnIndex(columnName) {
            var index = -1;
            $('table th').each(function(i) {
                if ($(this).data('sort') === columnName) {
                    index = i;
                    return false;
                }
            });
            return index;
        }

        //!!
        function deleteSelected() {
            var selectedIds = $('input[name="selected[]"]:checked').map(function(){
                return $(this).val();
            }).get();

            if (selectedIds.length === 0) {
                alert('Please select at least one record to delete.');
                return;
            }

            if (confirm('Are you sure you want to delete selected records?')) {
                $.ajax({
                    url: '{{ route('wastes.deleteSelected') }}',
                    type: 'DELETE',
                    data: {
                        "_token": "{{ csrf_token() }}",
                        "selectedIds": selectedIds
                    },
                    success: function(response) {
                        alert(response.message);
                        location.reload();
                    },
                    error: function(xhr) {
                        alert('Error deleting selected records.');
                    }
                });
            }
        }

        //!!
        function deleteRecord(WasteID) {
            if (confirm('Are you sure you want to delete this record?')) {
                $.ajax({
                    url: '/wastes/' + WasteID,
                    type: 'DELETE',
                    data: {
                        "_token": "{{ csrf_token() }}",
                    },
                    success: function(response) {
                        alert(response.message);
                        location.reload();
                    },
                    error: function(xhr) {
                        alert('Error deleting the record.');
                    }
                });
            }
        }
    </script>
    <script>
        $(document).ready( function () {
            $('#wasteTable').DataTable();
    });
    </script>
@endsection

2

Answers


  1. in route file order is important.
    first you wrote get than wrote resource and the end delete. its wrong.
    and in my opinion you can use manual routing and change delete to post method.

    otherwise if you want to use delete method you can

    "_method":"delete"
    

    to your ajax data and use POST method.

    see more: How to send a PUT/DELETE request in jQuery?

    your ajax should be like this:

               $.ajax({
                        url: '/wastes/' + WasteID,
                        type: 'POST',
                        data: {
                            "_token": "{{ csrf_token() }}",
                            "_method": "delete",
                        },
                        success: function(response) {
                            alert(response.message);
                            location.reload();
                        },
                        error: function(xhr) {
                            alert('Error deleting the record.');
                        }
                    });
    
    Login or Signup to reply.
  2. The console image reveals that you’re doing a DELETE request to /wastes which, per your routes configuration, doesn’t exist.

    You do have a resource URL that accept DELETE requests to /wastes/{waste}.

    That’s why you get a 405 on the request.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search