Ajax post giving null in laravel controller [duplicate] - php

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'

Related

Laravel 5.6 - Issue passing from jQuery to Laravel Controller

I'm having some problems passing from my blade file with an ajax request, to my Laravel controller. As far as I can tell I have set up my routes appropriately.
Route
Route::post('/aquarium/{id}/parameters', 'AquariumController#paramUpdate')->name('paramUpdate');
Laravel Function
use App\Aquarium;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
public function paramUpdate($id)
{
$params = $_POST['parameters'];
$aquarium = Aquarium::find($id);
$aquarium->parameters = $params;
$aquarium->save();
return "test";
//return redirect('/aquarium/'.$id);
}
Ajax request
var jsonParams = JSON.stringify(params);
$.ajax({
type: "POST",
url: "{{ route('paramUpdate', $aquarium->id) }}",
data: { parameters: jsonParams },
success: function(response) {
console.log(response);
},
error: function() {
console.log("Ajax error");
}
});
The goal is to pass the jsonParams variable to the controller, and then save it to the parameters field in the database. The database is configured and a record exists.
Fixed it - I added
<meta name="csrf-token" content="{{ csrf_token() }}">
to the header, and then
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
to the script. Figured it out by using the network tab to see the error being returned, and then some googling from there.

Laravel AJAX 404 for route

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'))
});

Laravel: Send Data to Controller via AJAX Without Form

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;

Laravel ajax internal servor 500 (internal server-error)

I have a shopping cart which is stored in session and I want to refresh the session without reloading the page
I have tried this:
View:
Add to cart
<script>
$(document).ready(function() {
$('#product').click(function(event) {
event.preventDefault();
let url = "{{ route('add-to-cart') }}";
let id = $(this).data('id');
$.ajax({
url: url,
type: 'POST',
data: {product_id: id, _token: "{{ Session::token() }}"}
})
.done(function() {
console.log("success");
})
.fail(function() {
console.log("error");
})
});
});
Route:
Route::post('/add-to-cart', 'ProductsController#addToCart')->name('add-to-cart');
ProductsController:
public function addToCart(Request $request)
{
if ($request::ajax()) {
$id = $request->product_id;
$product = Product::find($id);
if (Session::has('products')) {
$products = Session::get('products');
$products[] = $product;
Session::put('products', $products);
}
else {
$products = array($product);
Session::put('products', $products);
}
return response()->json();
}
}
And when I click add to cart it gives 500 (Internal Server Error) in the console
You're accessing the ajax() method statically (using ::), when you should be using -> instead:
if ($request->ajax()) {
Using the Laravel log file
As mentioned in the comments, Laravel is probably telling you this in storage/logs/laravel.log, complete with a long call-stack trace (the lines that you mentioned, beginning with "#38" and "#39"). Just scroll up to before "#1" and you'll find your culprit.
Laravel doesn't allow without passing X-CSRF-TOKEN,
following is my working example hope it helps you.
Route :
Route::post('block-user','UserController#BlockUser');
Now you need to add ajax setup before your ajax call so in
blade.php :
Add this in header
<meta name="csrf-token" content="{{ csrf_token() }}" />
My script like :
<script>
//Ajax setup
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
//Ajax call
$(".blockuser").bootstrapSwitch();
$('.blockuser').on('switchChange.bootstrapSwitch', function () {
var userid = $('#userid').val();
$.ajax({
url:'/block-user',
data:{user_id : userid},
type:'post',
success: function(data){
alert(data);
}
});
});
</script>
Controller :
public function BlockUser(Request $request)
{
$userid = $request->get('user_id');
//perform operation
}

TokenMismatchException RANDOM on ajax requests Laravel

How this can be explained?
Clean install Laravel
Using redis for session and cache
The problem occur only if I start the server on windows and only shows on Chrome.
Using a simple js function for ajax call:
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
data: {
_token: $('meta[name="csrf-token"]').attr('content')
}
});
for(var i = 0; i < 5; i++){
getUsers();
}
function getUsers() {
$.ajax({
url: '/users',
type: 'POST',
success: function(data) {
console.log(data);
}
});
}
Setting CSRF in meta <meta name="csrf-token" content="{{ csrf_token() }}" />
Returning a JSON with data:
public function users() {
$users = User::all();
return response()->json([
'users' => $users,
]);
}
At the final of the video you can see RANDOM TokenMismatchException even the token never change but sometime error occur.
https://www.youtube.com/watch?v=QDucHoP647g
I know this problem has been discussed from years but why does not exist a solution for this?
I also posted on laravel github but none of solutions did not solved my problem.
Why do you send the token twice? remove that data part from $.ajaxSetup()
And why are you using POST for getting users? use GET instead.

Categories