1
votes

I am trying to update some data via ajax in laravel 5, But I am facing MethodNotAllowed Http Exception.

So, I have created a resource route in web.php, an HTML form to get some data prefilled in the textboxes, and some ajax code.

Code For Web.php, prefixed via admin.

Route::resource('settings', 'OrganisationSettingsController', ['only' => ['edit', 'update', 'index', 'change-language']]);

Html Form Code

{!! Form::open(['id'=>'editSettings','class'=>'ajax-form','method'=>'PUT']) !!} //Input Elements Goes Here... {!! Form::close() !!} Ajax Call code

$('#save-form').click(function () {
    $.easyAjax({
        url: '{{ route('admin.settings.update', ['1']) }}',
        container: '#editSettings',
        type: "POST",
        redirect: true,
        file: (document.getElementById("logo").files.length != 0 || document.getElementById("login_background").files.length != 0) ? true : false
    })
});

When User Click on the update button the data must be updated, but I got http method not allowed exception in browser's console.

4
are you passing the CSRF ?Vidal
yes, I am passing CSRFHafiz Siddiq

4 Answers

1
votes

You are posting data. When you post data and use resource in your router laravel calls store function and your route does not let it (['only' => ['edit', 'update', 'index', 'change-language']).

for testing it add store function to your route and dd($request); you can see your request;

0
votes

You will need to spoof your method from your ajax call, assuming easyAjax allows a data attribute it should include:

data: {
    '_method' : 'PUT'
},

In addition, you will want to include your csrf token:

data: {
    '_method' : 'PUT',
    '_token' : '{{csrf_token()}}'
},

Note: '{{csrf_token()}}' will work as long as the script is part of the blade view. If not, then use a header:

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

If you need to use headers to include your csrf token, make sure to include the meta tag in the head portion of your document:

<meta name="csrf-token" content="{{ csrf_token() }}">

The full solution:

$('#save-form').click(function () {
    $.easyAjax({
        url: '{{ route('admin.settings.update', ['1']) }}',
        container: '#editSettings',
        type: "POST",
        data: {
          '_method' : 'PUT',
          '_token' : '{{csrf_token()}}'
        },
        redirect: true,
        file: (document.getElementById("logo").files.length != 0 || 
        document.getElementById("login_background").files.length != 0) ? true : false
    })
});

Read more about method spoofing.

0
votes

Do not use method => PUT in form. Instead, change to this

{!! Form::open(['id'=>'editSettings','class'=>'ajax-form','method'=>'POST']) !!}
@method('PUT')
@csrf

//input elements here

{!! Form::close() !!}

You need to change 'method'=>'POST' and add @method('PUT') and @csrf like added above

0
votes

Thanks @adam for your answer, this was exactly the problem. Finally I wrote the following code to get the expected result

$('#save-form').click(function () {
        $.easyAjax({
            url: '{{ route('admin.settings.update', ['1']) }}',
            container: '#editSettings',
            type: "POST",
            data: {
                'company_name': $('#company_name').val(),
                'company_email': $('#company_email').val(),
                'company_phone': $('#company_phone').val(),
                'website': $('#website').val(),
                'address': $('#address').val(),
                'currency_id': $('#currency_id').val(),
                'timezone': $('#timezone').val(),
                'locale': $('#locale').val(),
                'latitude': $('#latitude').val(),
                'longitude': $('#longitude').val(),
                '_method' : 'PUT',
                '_token' : '{{csrf_token()}}'
            },
            redirect: true,
            file: (document.getElementById("logo").files.length != 0 || document.getElementById("login_background").files.length != 0) ? true : false
        })
    });