I am working on a Laravel 5.3 solution. I try to call a POST route via AJAX from one of my views to update a set of categories but I get a 404 error everytime I call the route.
Interesting fact: During development I was able to call the route with the JS-code shown below successfully - but since I did some updates to the controller code itself it throws a 404 but no exception.
Here is my controller action:
public function updateTree( Request $request )
{
$data = $request->json()->all();
$result = BlogCategory::rebuildTree($data, false);
if($result > 0) {
return Response::HTTP_OK;
}
return Response::HTTP_NOT_MODIFIED;
}
And here the JS AJAX call:
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
var updateTree = function (e) {
var list = e.length ? e : $(e.target), output = list.data('output');
console.log(JSON.stringify(list.nestable('serialize')));
$.ajax({
url: '{{ action('BlogCategoryController#updateTree') }}',
type: "POST",
data: JSON.stringify(list.nestable('serialize'))
});
};
$(document).ready(function() {
$('#nestable2').nestable({
group: 1
}).on('change', updateTree);
});
The controller route is bound like that in web.php
Route::post( '/service/blog/categories/updatetree', 'BlogCategoryController#updateTree' );
As you might see, I am using the Laravel NestedSet module from LazyChaser here (https://github.com/lazychaser/laravel-nestedset).
Any input is much appreciated.
Cheers,
Jules
you having opening and closing quotes problem in your ajax url, use like this
$.ajax({
url: '{{ action("BlogCategoryController#updateTree") }}',
type: "POST",
data: JSON.stringify(list.nestable('serialize'))
});
Related
This question already has answers here:
How can I get useful error messages in PHP?
(41 answers)
Closed 8 months ago.
I'm trying to make a sortable table in my laravel app where the order also needs to be updated in the database, I'm trying to do it with jquery, ajax.
I tried to figure it out with this pieces of code:
JQuery/Ajax
$(document).ready(function () {
$('table tbody').sortable({
update: function (event, ui) {
$(this).children().each(function (index) {
if ($(this).attr('data-position') != (index + 1)) {
$(this).attr('data-position', (index + 1)).addClass('updated');
}
});
saveNewPositions();
}
});
});
function saveNewPositions() {
var positions = [];
$('updated').each(function () {
position.push([$(this).attr('data-index'), $(this).attr('data-position')]);
$(this).removeClass('updated');
});
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax({
url: 'cursos',
method: 'POST',
dataType: 'text',
data: {
'updated': 1,
'positions': positions,
'_token': '{{ csrf_token() }}'
},
})
Then in my web.php I created a post route:
Route::post('/cursos', function (Request $request){
return SectionCourseController::updateOrder($request);})->name('post');
In my controller I created this function:
public static function updateOrder(Request $request)
{
var_dump($request->positions);
foreach ($request->positions as $position) {
$index = $position[0];
$newPosition = $position[1];
$seccion = SectionCourse::findOrFail($index);
$seccion->order = $newPosition;
$seccion->save();
}
return response('success', 200);
}
When I'm trying to update the order, I'm having an error on the console of 500 (Internal Server Error).
[2022-06-14 14:16:18] local.ERROR: foreach() argument must be of type array|object, null given {"userId":1,"exception":"[object] (ErrorException(code: 0): foreach() argument must be of type array|object, null given
Sorry if I'm doing something bad on Ajax, this is the first time I try to do something on it.
I've done something very similar to this, so as I see it right now you are firstly missing a csrf token, so in the view add this below the code where you declare the $('updated') each.
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax({
method: 'POST',
dataType: 'json',
url: 'cursos', // No {{}} needed here
data: {
update: 1,
orders: orders,
_token: '{{ csrf_token() }}'
},
});
Next your controller is a mess. So rewrite it to fit at least some of laravels writing standards. Something like this
public function updateOrder(Request $request)
{
foreach ($request->positions as $position) {
$index = $position[0];
$newPosition = $position[1];
$seccion = SectionCourse::findOrFail($index);
$seccion->order = $newPosition;
$seccion->save();
}
return response('success', 200);
}
Also add the following when declaring .sortable
axis: 'y',
containment: 'parent',
update: ...
Add a meta-tag to each page, or master layout
<meta name="csrf-token" content="{{ csrf_token() }}"> and add to your js page
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
Dont forget to add data inside
$.ajax({
url: "test",
type:"POST",
data: { '_token': token, 'someOtherData': someOtherData },
There is 2 cases for 500 internal server error
you had not put the {csrf} token there when sending request through ajax.
Use new FormData() object while sending response through ajax and use these params with processData: false,contentType: false,type: 'POST'
I try to make POST-request to method of admin controller using AJAX (from admin part). My JS code:
<script>
$(".remove-request-btn").on('click', function () {
let request_id = $(this).data('request-id');
let confirm_result = confirm('Are you sure you want to delete this request?');
if (confirm_result) {
$.ajax({
url: 'index.php?route=extension/x_feedback/settings/removeRequest&token={{ token }}',
method: 'post',
dataType: 'json',
data: {request_id: 11},
success: function(data) {
if (data.status === 'ok') {
location.reload();
}
},
error: function () {
alert('Error');
}
});
}
});
</script>
My method:
public function removeRequest()
{
$this->response->addHeader('Content-Type: application/json');
$this->response->setOutput(json_encode(
[
'status' => 'ok'
]
));
}
I expect json in the response but get following:
I tried to add admin into the url like '/admin/index.php?route=extension/x_feedback/button/feedbackRequest&token={{ token }}'
But it doesn't help. Can you help me please what I'm doing wrong? Thank you!
1-please add bellow code into controller method
$data['token'] = $this->session->data['user_token'];
2- use javascript into .twig file - not external js file.
In OC3 is used user_token instead token
so you must use this url:
url: 'index.php?route=extension/x_feedback/settings/removeRequest&user_token={{ user_token }}',
And do not forget declare user_token in the corresponding controller file:
$data['user_token'] = $this->session->data['user_token'];
I want to call storeProduct controller method in ajax URL.
url: './product_catalog/storeProduct'
How to call a method in this URL?
I want to store product_id and campaign id in the database.
Page not found error occurs.
Route :
Route::get('product_catalog','front\ProductCatalogController#showProductCatalogForm');
Route::post('product_catalog',['as' => 'storeProduct', 'uses' => 'front\ProductCatalogController#storeProduct']);
Ajax :
$(".my_form").submit(function(event) {
event.preventDefault(); //prevent default action
var product_id = $(this).find('#product_id').val();
var campaign_id = $(this).find('#campaign_id').val();
console.log(product_id);
console.log(campaign_id);
$.ajax({
type: "POST",
url: './product_catalog/storeProduct',
data: {
'product_id': product_id,
'campaign_id': campaign_id
},
success: function(data) {
alert(data);
console.log(data);
}
});
});
Controller :
public function showProductCatalogForm()
{
//if($_GET["campaign"]!=="")
$campaign=$_GET["campaign"];
return view('front.product_catalog');
}
public function storeProduct(Request $request)
{
$this->validate($request, $this->rules);
$input=Input::all();
$campaign_product=ProductCatalog::create($input);
return redirect('product_catalog');
}
url: {{ url('/product_catalog/storeProduct') }},
your route should be
Route::get('/product_catalog','front\ProductCatalogController#showProductCatalogForm');
your ajax url should be
type: "POST",
url: '/product_catalog',
Or you can use route(); i recommend dont use url() because any time if you want change urls you will need to change it manually.which is not good for app.urls could be 100 or 1000 to change.it could be dangers.
you should try name route like this
Route::get('/product_catalog','front\ProductCatalogController#showProductCatalogForm')->name('product_catalog');
and your ajax url
type: "POST",
url: {{ route('product_catalog') }},
Why you are adding "." In ./product-catalog !
Just use /product-catalog
Use "." when you want to search for folder or any directory or any file in your project directory or any other folder and you are not sure where the file is
Dont use in url when there is a route for the link
try this if you have wrote javascript inside blade :
$(".my_form").submit(function(event) {
event.preventDefault(); //prevent default action
var product_id = $(this).find('#product_id').val();
var campaign_id = $(this).find('#campaign_id').val();
console.log(product_id);
console.log(campaign_id);
$.ajax({
type: "POST",
url: '{{route('storeProduct')}}',//this is only changes
data: {
'product_id': product_id,
'campaign_id': campaign_id
},
success: function(data) {
alert(data);
console.log(data);
}
});
});
use this without the dot before slash.
url: '/product_catalog/storeProduct',
You could use
url:"{{route('route.name')}}"
and it works for me. You could check it by
console.log("{{route('route.name')}}");
inside your script.
I need to send data via JS to a Laravel controller on a button click. I'm not using any form because the data is being created dynamically.
Every time i try to send the data, i get an Internal Server Error (500), but unable to catch that exception in the controller or the laravel.log file.
Here's what i'm doing:
Route:
Route::post('section/saveContactItems', 'SectionController#saveContactItems');
Controller:
public function saveContactItems($id, $type, $items, $languageID = "PT"){ ... }
JS:
$('button').on("click", function (evt) {
evt.preventDefault();
var items = [];
var id = $("#id").val();
var languageID = $("#languageID").val();
var data = { id: id, type: type, items: JSON.stringify(items), languageID: languageID };
$.ajax({
url: "/section/saveContactItems",
type: "POST",
data: data,
cache: false,
contentType: 'application/json; charset=utf-8',
processData: false,
success: function (response)
{
console.log(response);
}
});
});
What am i doing wrong? How can i accomplish this?
UPDATE: Thanks to #ShaktiPhartiyal's answer (and #Sanchit's help) i was able to solve my issue. In case some else comes into a similar problem, after following #Shakti's answer i wasn't able to access the data in the controller. So, i had to stringify the data before sending it to the server:
data: JSON.stringify(data),
You do not need to use
public function saveContactItems($id, $type, $items, $languageID = "PT"){ ... }
You have to do the following:
public function saveContactItems()
{
$id = Input::get('id');
$type = Input::get('type');
$items = Input::get('items');
$languageID = Input::get('languageID');
}
and yes as #Sanchit Gupta suggested you need to send the CSRF token with the request:
Methods to send CSRF token in AJAX:
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
If you use this approach you need to set a meta tag like so:
<meta name="csrf-token" content="{{csrf_token()}}">
or
data: {
"_token": "{{ csrf_token() }}",
"id": id
}
UPDATE
as #Sanchit Gupta pointed out use the Input facade like so:
use Input;
I have created a like and dislike a button and store the info through ajax in Laravel 5.2. I am using wamp as my localhost.
At first, I saw sometimes the like and dislike was counted, and sometimes they weren't.
So, I tried to see it in the console through console.log(), and found 500(internal Server Error) in some of my clicks.
I also made sure the csrf token is provided properly.
I don't know how to deal with an error which sometimes come and sometimes doesn't.
this is my likeajax.js :
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
var postId=0;
$('.option1').on('click', function (event) {
event.preventDefault();
$('event').attr('disabled', 'disabled');
postId = event.target.parentNode.parentNode.parentNode.parentNode.dataset['postid'];
$.ajax({
method: 'GET',
url: urlLike,
data: {postId: postId, _token: token},
})
});
$('.optionx').on('click', function (event) {
event.preventDefault();
$('event').attr('disabled', 'disabled');
postId = event.target.parentNode.parentNode.parentNode.parentNode.dataset['postid'];
$.ajax({
method: 'GET',
url: urlDislike,
data: {postId: postId, _token: token},
})
});
this is my LikeController:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Depress;
use App\Http\Requests;
class LikeController extends Controller
{
public function postLike(Request $request)
{
$post_id = $request['postId'];
$post = Depress::find($post_id);
$post->like = $post->like+1;
$post->save();
return null;
}
public function postDislike(Request $request)
{
$post_id = $request['postId'];
$post = Depress::find($post_id);
$post->dislike = $post->dislike+1;
$post->save();
return null;
}
}
this is in my like layout.blade.php,
<script>
var token = "{{ csrf_token() }}";
var urlLike = '{{ route('like') }}';
var urlDislike = '{{ route('dislike') }}';
</script>
UPDATE:
though when I go to the page : http://localhost:8000/dislike ,
it shows
MethodNotAllowedHttpException in RouteCollection.php line 218:
Any help will be really appreciated.
The problem is that you $post_id is NULL.
Try $request->input('postId') instead of $request['postId'].
Also you should consider using POST instead of GET.