When using Laravel I can't get an ajax call to pass data to a class method

I’m very new to Laravel.

I would like to pass two variables from an ajax call to a method within a class.

My ajax call (derived from various Google searches) is:

    var token = $('meta[name="csrf-token"]').attr('content');
    var inputValue = "Testing";
    var anotherInput = "Testing2";
    var data = {};
    data.anotherInput = anotherInput;
    data.inputValue = inputValue;
    data._method = 'POST';
    data._token = token;

            //data: JSON.stringify(data),
        $.ajax({
            url: postUrl,
            type: 'POST',
            headers: {
                'X-CSRF-TOKEN': token
            },
            data: JSON.stringify(data),
            dataType: 'json',
            contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
            processData: false,
            success:function(response)
            {
                console.log(response);
            },
            error: function(response) {
                console.log(response);
            }

        });

The var "postUrl" is set in my layout.blade.php here:

    <script>
      var postUrl = "{{ route('filepathtest') }}";
    </script>

The top of my Controller Class is:

namespace App\Http\Controllers;

use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
 // use Request; 
use Illuminate\Support\Facades\Input;
use Illuminate\Http\Response;
use App\Models\MainSettings;
use App\Http\Requests\MainSettingsRequest;




class MainSettingsController extends Controller
{
    private string $messageTitle = "";
    private $messageText = array();

    /**
     * Corrects path and checks it points to something.
     */
    public function filePathTest(Request $request)
    {
        $data = $request->all();    
        $response = array(
          'msg' => $data,
        );
        return response()->json($response); 
 
    }

And, finally, my route is:

Route::match(array('GET','POST'),'filepathtest', [MainSettingsController::class, 'filePathTest'])->name('filepathtest');

My response gets logged to Console.Log and I see this:

enter image description here

I’ve tried lots of ways of accessing the variables from the Controller but to no avail?
I’ve tried:

$data = $request->input('anotherInput');

And:

$data = $request->anotherInput;

And:

$data = $request['anotherInput'];

And:

$data = $request->post('anotherInput');

And:

$data = $request->request('anotherInput');

But they all seem to return null apart from the last one gives me an error (unless I just "use Request;" at the top instead of "use Illuminate\Http\Request;") ?

>Solution :

So this seems to be a combination of factors of your $.ajax() request. At a minimum, this should work for POST requests:

$.ajax({
  type: 'POST', // or 'PATCH', 'DELETE', etc.
  url: postUrl, // Any valid URL from your Laravel Routes or other external URL
  data: postData // Any plain JS object, or `FormData`, etc.
  // ...
});

In this case, there were a few issues:

  1. data: JSON.stringify(data)

In this case, you were encoding your data object as a single String, and sending that to the controller. $request->all() was using that JSON string as an Array index, hence the weird ['{"anotherInput":"Testing2", ...}' => null] output when logging via \Log::info($request->all());

This should simply be data: data, or even just data using JS object shorthand.

  1. processData: false

I’m not familiar with this setting, but you can review the $.ajax() documentation to see when it is appropriate to use this: https://api.jquery.com/jquery.ajax/

  1. dataType, contentType and headers

There wasn’t anything wrong here per-se, but review if these are actually needed when making the AJAX request. If the _input key is included in your data, you can probably omit headers, but I doubt it would hurt to send it twice.

So, all in all, your code should function when refactored to:

$.ajax({
  data: {
    inputValue: 'Testing',
    anotherInput: 'Testing2',
    '_method': 'POST',
    '_token': $('meta[name="csrf-token"]').attr('content'),
  },
  type: 'POST',
  url: postUrl,
  success: function(response) {
    console.log(response);
  },
  error: function(response) {
    console.log(response);
  }
});

On the backend, $request->all() should return an array with 4 indices based on the data sent, and $request->input(...) should return the value of any of those indices, or null if specifying an invalid index.

Leave a Reply