0

I've been stucked on this line of code that Im doing. It says that mthod is not allowed however I already made some fix to accept the request

Services Controller

public function peakmode(Request $request, $id)
{
    $command = new \App\BizCommands\UpdatePeakmodeServices();
    $arr = $request->all();
    //$arr["merchant_id"] = $this->get_id();
    $service->merchant_id = 1;
    $arr["id"] = $id;
    $ret = $command->execute($arr, Auth::user());
    //return response()->json(['success'=> ($ret->error_code==0), 'message'=> $ret->message]);

    $message = array('message' => 'Service Successfully Updated!');
    return redirect()->back()->with($message);
}

Blade Form

<form action="{{ route('services.peakmode', $service->id) }} ">
{{method_field('PUT')}}
<input type="checkbox" name="onoffswitch" class="onoffswitch-checkbox" id="serviceswitch-7838" service-id="{{ $service->id }}"> 
<label class="onoffswitch-label" for="serviceswitch-7838"> <span class="onoffswitch-inner"></span> <span class="onoffswitch-switch"></span> </label>

Ajax Script

$(".onoffswitch .onoffswitch-checkbox").on("change",function(e){
  service_id = $(this).attr('service-id');
  if($(this).is(':checked') ){
    peak = 1;
  }else{
    peak = 0;
  }
  $.ajax({
    method: "POST",
    url: $(this).prop('action'),
    data: { 
      service_id: service_id,
      peak: peak,
      '_method': 'PUT',
      "_token": "{{ csrf_token() }}",
    }
  })
  .done(function(response){
    console.log(response);
  });
});

Route

Route::post('/merchant/services/peakmode/{id}', 'Merchant\ServicesController@peakmode')->name('services.peakmode');

4 Answers4

1

You have to add method only POST in ajax and then you have to add X-CSRF-TOKEN like this,

Laravel Documentation https://laravel.com/docs/5.7/csrf#csrf-x-xsrf-token

In addition to checking for the CSRF token as a POST parameter, the VerifyCsrfToken middleware will also check for the X-CSRF-TOKEN request header. You could, for example, store the token in a HTML meta tag:

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

Then, once you have created the meta tag, you can instruct a library like jQuery to automatically add the token to all request headers. This provides simple, convenient CSRF protection for your AJAX based applications:

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

Now, your ajax request should look like,

$.ajax({
    headers: {
        'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
    },
    type:'POST',
    url: $(this).prop('action'),
    data: { 
      service_id: service_id,
      peak: peak,
    }
    success: function(result) {
        console.log(result);
    },
    error: function(result){
        console.log(result);
    }
});

If any confusion feel free to ask.

Here is how you can make patch request with laravel and ajx, see this question PATCH AJAX Request in Laravel

Sagar Gautam
  • 9,049
  • 6
  • 53
  • 84
  • As we can see here [getTokenFromRequest](https://github.com/laravel/framework/blob/5.5/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php#L137) Laravel can read both `_token` and `X-CSRF-TOKEN`, so there is no obligation to use just `X-CSRF-TOKEN`. – ako Dec 09 '18 at 13:05
  • The 500 error usually is a PHP error, check your logic in the controller. You can use the console too – Flash Dec 09 '18 at 14:40
  • @d'reaper check your controller code there should be something wrong. – Sagar Gautam Dec 09 '18 at 16:28
0

You have used POST instead of PUT

Route::put('/merchant/services/peakmode/{id}', 'Merchant\ServicesController@peakmode')->name('services.peakmode');

I am not sure if PUT is used in AJAX as well but u could try that if that alone fails.

Unprofessionally i myself use all POST and GET alone so i dont have to deal with PUT and DELETE

my workaround:

<form action="{{ route('services.peakmode', $service->id) }} " method="POST">
//make sure not to include the {{method line}}

and on AJAX call

$.ajax({
    method: "POST",
    url: $(this).prop('action'),
    data: { 
      service_id: service_id,
      peak: peak,
      "_token": "{{ csrf_token() }}",
    }
  })

and the route

Route::post('/merchant/services/peakmode/{id}', 'Merchant\ServicesController@peakmode')->name('services.peakmode');
Flash
  • 1,105
  • 14
  • 16
  • well I already change that to put. but still getting this error result on console.log /merchant/services 405 (Method Not Allowed) –  Dec 09 '18 at 12:46
  • so i suggest u work with POST alone, usually does the job all the time for me – Flash Dec 09 '18 at 12:47
  • The 500 error usually is a PHP error, check your logic in the controller. You can use the console too – Flash Dec 09 '18 at 14:41
0

Change route to:

Route::match(['POST', 'PUT'], '/merchant/services/peakmode/{id}', 'Merchant\ServicesController@peakmode')->name('services.peakmode');
ako
  • 2,000
  • 2
  • 28
  • 34
0

You have added route of method POST and used method PUT in form change method PUT to POST in form

 {{method_field('POST')}}
Leena Patel
  • 2,423
  • 1
  • 14
  • 28