The PATCH method is not supported for this route - php

i can't find the problem, i want to update the data to database, but i get Patch method is not support. i can't find the problem, i check from book refrence have not different, but in this case can't run for update.
this is my web.php
Route::get('/home', [App\Http\Controllers\HomeController::class, 'index'])->name('home');
Route::get('laravel/data', 'LaravelController#listData')->name('laravel.data');
Route::resource('laravel', 'LaravelController');
this my controller
/**
* Update the specified resource in storage.
*
* #param \Illuminate\Http\Request $request
* #param int $id
* #return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
$laravel = Laravel::find($id);
$laravel = $request['id'];
$laravel->tanggal_pemasangan = $request['tanggal'];
$laravel->pitstop = $request['pitstop'];
$laravel->merk_ban = $request['merk_ban'];
$laravel->no_series_ban = $request['series_ban'];
$laravel->jenis_mobil = $request['jenis_mobil'];
$laravel->plat_nomor = $request['plat_mobil'];
$laravel->posisi_ban = $request['posisi_ban'];
$laravel->status = $request['status'];
$laravel->update();
}
my form.blade
<form class="form-horizontal" data-toggle="validator" method="POST">
#method('POST')
#csrf
and my ajax
$('#modal-form form').validator().on('submit', function(e){
if(!e.isDefaultPrevented()){
var id = $('#id').val();
if(save_method == "add") url = "{{ route('laravel.store') }}"
else url = "laravel/"+id;
$.ajax({
url : url,
type: "POST",
data: $('#modal-form form').serializa(),
success : function(data){
$('#modal-form form').modal('hide');
table.ajax.reload();
},
error: function(){
alert("Tidak dapat menyimpan data!");
}
});
return false;
}
});
function editForm(id){
save_method = "edit";
$('input[name = _method]').val('PATCH');
$('#modal-form form')[0].reset();
$.ajax({
url : "laravel/"+id+"/edit",
type: "GET",
dataType: "JSON",
success: function(data){
$('#modal-form').modal('show');
$('.modal-title').text('Edit Data');
$('#id').val(data.id);
$('#tanggal').val(data.tanggal_pemasangan);
$('#pitstop').val(data.pitstop);
$('#merk_ban').val(data.merk_ban);
$('#series_ban').val(data.no_series_ban);
$('#jenis_mobil').val(data.jenis_mobil);
$('#plat_mobil').val(data.plat_nomor);
$('#posisi_ban').val(data.posisi_ban);
$('#status').val(data.status);
},
error: function(){
alert("Tidak dapat menampilkan data!");
}
});
}
every time i want to do update, always give me error 405 this method is not support

Verify that your server supports the HTTP request: "PUT".
In your blade.php file add the #method('put') inside the form.
<form method="POST">
#method('PUT')
#csrf
...
</form>
Considering that resource type controllers generate the routes for you, perhaps you should use the php artisan route:list command to check the update route parameters.
Some examples of generated routes for resource type controllers, here.
Now maybe it can be a route hierarchy problem, try changing the order of your routes like this.
Route::resource('laravel', 'LaravelController');
Route::get('laravel/data', 'LaravelController#listData')->name('laravel.data');

Route::resource() #update method uses PATCH|PUT verb instead of POST
In your case you use POST method so the request will be not compatible, You need to use PATCH or PUT instead of POST in your type in ajax or in the form if necessary

Related

Laravel undefined variable into blade after calling from JSON

I've Signup form in my website. It was properly submitting before. Now I wanted to submit my form using ajax and wanted to return a variable from controller into JSON that I will use into blade file.
The form is submitting and values are showing into database but after redirection, it returns error.
Undefined variable: seller in report blade
I tried to decode my variable to make it work but still the same error.
How would I make it work?
Report-Blade
#foreach(json_decode($seller, true) as $row)
<a href="{{route('Report', $row->id) }}" >
{{ __('Show Report of ')}} {{$row->car_title}}
</a>
#endforeach
Controller
$seller = Sellers::take(1)->latest()->get();
return response(view('report',array('seller'=>$seller)),200, ['Content-Type' =>
'application/json']);
JavaScript
$("#submit-all").click(function(e){
e.preventDefault();
var _token = $('input[name="_token"]').val();
$.ajax({
type: "post",
url: "{{ route('form_for_private_sellers') }}",
data : $('#msform').serialize() + "&_token=" + _token,
dataType: 'JSON',
beforeSend: function(){
// Show loading image
$("#se-pre-con").show();
},
success: function(data) {
window.location = "http://127.0.0.1:8000/report/";
},
complete:function(data){
// Hide loading image
$("#se-pre-con").hide();
}
});
});
As understood from your comments,
window.location = "http://127.0.0.1:8000/report/";
will hit the route
Route::get('/report', function () {
return view('report');
})->name('private_seller_report');
Report blade expects a variable named $seller, and it is not being sent from the route. You would need to change the route to something similar to this:
Route::get('/report', function () {
$sellers = Seller::get(); //your logic
return view('report', ['seller' => $sellers]);
})->name('private_seller_report');
Alternatively you can point the route to a method in a controller if you want to avoid bulking up your routes.
you need two route for this
first for rendering blade
return view('report');
and the second for fetch seller
$seller = Sellers::latest()->take(1)->get();
return $seller

Can't pass parameters using AJAX + Symfony 4

I'm using AJAX to request client names from my DB using autocomplete() inside an input #descricao. It requests a route that I created inside Symfony 4 (/acao).
The problem is that I'm trying to set a parameter (/acao?parametro=clientname) but I'm get an error:
Could not resolve argument $parametro of
"App\Controller\DefaultController::filter()", maybe you forgot to
register the controller as a service or missed tagging it with the
"controller.service_arguments"?
I tried to change my routes.yaml:
acao:
path: /acao
controller: App\Controller\DefaultController::filter
methods: GET
but it didn't work.
script.js:
$( "#descricao" ).autocomplete({
source: function( parametro, response ) {
$.ajax({
url: '/acao',
dataType: "json",
data: {
parametro: $('#descricao').val()
},
success: function(data) {
response(data);
}
});
}
});
DefaultController:
/**
* #param string $parametro
* #return JsonResponse
* #Route("/acao", name="acao", methods="GET")
*/
public function filter(string $parametro){
$em = $this->getDoctrine()->getManager()->getRepository(Clients::class)
->createQueryBuilder('c')
->andWhere('c.name_fantasy ilike :parametro')
->setParameter('parametro','%'.$parametro.'%')
->getQuery()
->getArrayResult();
return new JsonResponse($em);
}
What am I doing wrong?
ANSWER:
I managed to make it work using POST and changing table name c.name_fantasy to values:
Controller:
/**
* #param Request $request
* #return JsonResponse
* #Route("/acao", name="acao", methods="POST")
*/
public function filter(Request $request){
$q = strtoupper(trim($request->request->get('parametro')));
$em = $this->getDoctrine()->getManager()->getRepository(Clients::class)
->createQueryBuilder('c')->select('c.name_fantasy AS value')
->andWhere('c.name_fantasy like :parametro')
->setParameter('parametro', '%'.$q.'%')
->getQuery()
->getArrayResult();
return new JsonResponse($em);
}
AJAX:
$( "#descricao" ).autocomplete({
source: function( parametro, response ) {
$.ajax({
url: '/acao',
dataType: 'json',
method: 'POST',
data: {
parametro: $('#descricao').val()
},
success: function(data) {
if (data.length > 0) {
response(data);
}
else {
data = '';
response(data)
}
},
});
}
});
Firstly, you dont need use routes.yaml for routing, if you use the Route Component:
Symfony\Component\Routing\Annotation\Route
So just delete that stuff from routes.yaml.
EDITED:
/**
* #param Request $request
* #return JsonResponse
* #Route("/acao", name="acao", methods="GET", options={"expose"=true})
*/
public function filter(Request $request)
{
//you should strip and trim the parameter, like (just basic):
$clientName = strip_tags(
trim($request->query->get('parametro'))
);
// ...
}
Where Request is Symfony\Component\HttpFoundation\Request <-- you need add to the use statements!
If this not working for you, with your original ajax (what in your question), try on this way:
// ...
let formData = new FormData();
formData.append("parametro", $('#descricao').val());
$.ajax({
url: '/acao',
// ...
data : formData,
// ...
JUST A TIP:
I recommend, use the symfony/bundles/FOSJsRoutingBundle. You can link your routes in js like this:
import Routing from '../../vendor/friendsofsymfony/jsrouting-bundle/Resources/public/js/router';
import Routes from '../../public/assets/js/fos_js_routes.json';
Routing.setRoutingData(Routes);
// ...
$.ajax({
//acao is your route name and you route in this case:
url: Routing.generate("acao"),
Dump the latest added routes, with this command:
php bin/console fos:js-routing:dump --format=json --target=public/assets/js/fos_js_routes.json
...

Link to a specific part of a page

I have a div that has lots of posts which is created dynamically from the database. The div has input for comment facility as well. I have no problems in posting the comments and I do it using a POST method. Then I redirect to the page using return redirect('/'); method. But it links to the beginning to the page which doesn't create a good impression on the user. The user might be in the middle of the page and when he/she comments he will go to the beginning of the page and will have to scroll down again. Luckily, I have the divs with class equal to the post_id. So, isn't there any method to go to the post in which the user posted using that class?
attach the id with the url like /#post-id
Inside your contorller where you are processing and saving the comments:
use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\URL;
public function yourCommentSaveFunction()
{
...
//Get the Post ID and store in $postid
return Redirect::to(URL::previous() . '#' .$postid);
}
This should work fine.
But the best way would be to use AJAX to post comments.
Edit (As request by OP)
THE AJAX METHOD
Controller will be something like:
public function saveComment(Request $request)
{
//you do the saving part..
...
$comment = $request->comment;
//after saving the comment return a json response
//you can also send other varibales like username, created at etc..
return Response::json(array(
'success' => true,
'comment' => $comment,
));
}
Route:
Route::post('/save-comment', [
'as' => 'save-comment',
'uses' => 'yourController#saveComment',
]);
And your View:
<form action="{{ route('save-comment') }}" class="comment-form">
<input type="text" name="comment">
<input type="submit" name="submit">
<input type="hidden" name="_token" value="{{ csrf_token() }}"
<div class="comment"></div>
</form>
<script>
$('.comment-form').submit(function(event){
event.preventDefault();
var comment = $this.val();
var token = $('.token').val();
var $url = "{{ route('save-comment') }}";
$.ajax({
url: route,
type: 'POST',
data: {_token: token, comment: comment},
dataType: 'JSON',
success: function (data) {
$(".comment").append('<div class="new-comment">' +data.comment +'</div>');
},
error: function(data) {
console.log("Something went wrong");
}
});
});
</script>
Please note: this is just a sample code.

AJAX POST request in Laravel [duplicate]

This question already has answers here:
jQuery add CSRF token to all $.post() requests' data
(7 answers)
Closed 4 years ago.
I have an AJAX request which is a GET request.
/**
* AJAX Like function
*/
$(".like").click(function (e) {
e.preventDefault(); // you dont want your anchor to redirect so prevent it
$.ajax({
type: "GET",
// blade.php already loaded with contents we need, so we just need to
// select the anchor attribute href with js.
url: $('.like').attr('href'),
success: function () {
if ($('.like').hasClass('liked')) {
$(".like").removeClass("liked");
$(".like").addClass("unliked");
$('.like').attr('title', 'Like this');
} else {
$(".like").removeClass("unliked");
$(".like").addClass("liked");
$('.like').attr('title', 'Unlike this');
}
}
});
});
Where the URL is: http://127.0.0.1:8000/like/article/145
And is grabbed via the href attribute of .like, the markup of which looks like this:
<div class="interaction-item">
#if($article->isLiked)
<a href="{{ action('LikeController#likeArticle', $article->id) }}" class="interactor like liked" role="button" tabindex="0" title="Unlike this">
#else
<a href="{{ action('LikeController#likeArticle', $article->id) }}" class="interactor like unliked" role="button" tabindex="0" title="Like this">
#endif
<div class="icon-block">
<i class="fas fa-heart"></i>
</div>
</a>
</div>
The LikeController looks like this:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\User;
use App\Like;
use App\Article;
use App\Event;
use Illuminate\Support\Facades\Auth;
class LikeController extends Controller
{
/**
* Display all liked content for this user
*/
public function index()
{
$user = Auth::user();
$articles = $user->likedArticles()->get();
$articleCount = count($articles);
$events = $user->likedEvents()->get();
$eventCount = count($events);
return view('pages.likes.index', compact('articles', 'articleCount', 'events', 'eventCount'));
}
/**
* Handle the liking of an Article
*
* #param int $id
* #return void
*/
public function likeArticle($id)
{
// here you can check if product exists or is valid or whatever
$this->handleLike(Article::class, $id);
return redirect()->back();
}
/**
* Handle the liking of an Event
*
* #param int $id
* #return void
*/
public function likeEvent($id)
{
// here you can check if product exists or is valid or whatever
$this->handleLike(Event::class, $id);
return redirect()->back();
}
/**
* Handle a Like
* First we check the existing Likes as well as the currently soft deleted likes.
* If this Like doesn't exist, we create it using the given fields
*
*
* #param [type] $type
* #param [type] $id
* #return void
*/
public function handleLike($type, $id)
{
$existingLike = Like::withTrashed()
->whereLikeableType($type)
->whereLikeableId($id)
->whereUserUsername(Auth::user()->username)
->first();
if (is_null($existingLike)) {
// This user hasn't liked this thing so we add it
Like::create([
'user_username' => Auth::user()->username,
'likeable_id' => $id,
'likeable_type' => $type,
]);
} else {
// As existingLike was not null we need to effectively un-like this thing
if (is_null($existingLike->deleted_at)) {
$existingLike->delete();
} else {
$existingLike->restore();
}
}
}
}
I think it's extremely bad practice to update a database via a GET request
So, I changed the Route to use POST and updated the AJAX call to:
/**
* AJAX Like function
*/
$(".like").click(function (e) {
e.preventDefault(); // you dont want your anchor to redirect so prevent it
$.ajax({
type: "POST",
// blade.php already loaded with contents we need, so we just need to
// select the anchor attribute href with js.
url: $('.like').attr('href'),
data: {
_token: '{{ csrf_token() }}'
},
success: function () {
if ($('.like').hasClass('liked')) {
$(".like").removeClass("liked");
$(".like").addClass("unliked");
$('.like').attr('title', 'Like this');
} else {
$(".like").removeClass("unliked");
$(".like").addClass("liked");
$('.like').attr('title', 'Unlike this');
}
}
});
});
As you can see, I've changed the method and added in the CSRF token, however, I get an error:
POST http://127.0.0.1:8000/like/article/145 419 (unknown status)
send # app.js:14492
ajax # app.js:14098
(anonymous) # app.js:27608
dispatch # app.js:10075
elemData.handle # app.js:9883
app.js:14492 XHR failed loading: POST "http://127.0.0.1:8000/watch/article/145".
What is the best way to debug what's going on?
Update
By adding: <meta name="csrf-token" content="{{ csrf_token() }}"> would it interfer with my normal use of `#csrf' in my forms?
Also, I added a fail callback to the request
}).fail(function (jqXHR, textStatus, error) {
// Handle error here
console.log(jqXHR.responseText);
});
Another update
As you have all kindly pointed out, in the documentation here, it does indeed say, set the meta CSRF attribute, I even had an error in my console saying this wasn't defined, but I misinterpreted the error.
Why though, in some tutorials, do people add the CSRF token to the data array?
Look at this. You can't use {{ csrf_token() }} in your JS.
Try this in your html :
<meta name="csrf-token" content="{{ csrf_token() }}">
And this in your JS :
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
If you have multiple ajax call in single file then you can do via this. The following code will working for all your AJAX requests.
Try this in your html :
<meta name="csrf-token" content="{{ csrf_token() }}">
And this in your JS :
$(document).ready(function() {
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
});

Laravel 5.4 - MethodNotAllowedHttpException in RouteCollection.php line 233

In my laravel 5.4 app, i have a crud module. for the edit bit, the data is rendered in a bootstrap modal. the data is pulled successfully but on hitting the update button, the error shown is returned.
here's my blade form that's rendered in the modal:
<form id="formEdit" class="form-horizontal" role="form" method="put">
//form elements
</form>
here's the ajax that handles it:
//edit_id is defined globally
$('#updateClass').click(function(){
var name = $("#formEdit #name").val();
var status = ($('#formEdit #status').prop("checked") == true) ? 1 : 0;
var token = $('meta[name="csrf-token"]').attr('content');
var id = edit_id;
var url = "classes/update/"+id;
var formdata = {
'name' : name,
'status' : status,
'_token' : token
};
$.ajax({
method: "PUT",
url: url,
data: formdata,
dataType: "json"
})
.done(function(data) {
//
})
.fail(function(data) {
//
});
});
});
updateClass is the button that displays the edit form on the modal..
here's my routes in web.php:
Route::resource('classes', 'ClassesController');
Route::group(['prefix' => 'admin'], function () {
Route::get('classes', 'ClassesController#index');
Route::get('classes/edit/{id}', 'ClassesController#edit');
Route::put('classes/update/{id}', 'ClassesController#update');
});
and finally, my update function in the classes controller:
public function update(Request $request, $id)
{
$validator = $this->validator($request->all());
$errors = $validator->errors();
$errors = json_decode($errors);
if ($validator->passes())
{
Dl_class::find($id)->update($request->all());
return response()->json();
}
else
{
return response()->json($errors, 422);
}
}
what i'm i missing?
To send PUT request from form you need to send a hiddne input element named as method. Something like this:
<input type='hidden' name='_method' value='PUT'>
there is a helper method to do the same like:
{{ method_field('PUT') }}
Only then Laravel can recognize your PUT request.
Or alternatively, you can enclose this value to your ajax call also Something like:
var formdata = {
'name' : name,
'status' : status,
'_token' : token,
'_method' : 'PUT'
};

Categories