'Laravel ajax 422 (unprocessable Entity)

I have a registration form in laravel which is working fine without ajax. But I want to post the data using Ajax. I wrote Ajax code to post but I am getting error message in console ie 422 (unprocessable Entity)

registration.blade.php

@extends('layouts.layout')

@section('content')
    <div class="container">
        <div class="row">
            <div style="width:100%; max-width: 500px; margin: auto;">
                <h3 class="text-center"><u>Register with us</u></h3>
                <hr>
                <form id="registrationForm" method="post" action="/submitRegistrationData" enctype="multipart/form-data">
                    {{ csrf_field() }}
                    <div class="form-group">
                        <label>First name: <span><em>{{$errors->first('fname')}}</em></span></label>
                        <input type="text" class="form-control" id="fname" name="fname" value="{{ old('fname') }}">
                    </div>
                    <div class="form-group">
                        <label>Last name: <span><em>{{$errors->first('lname')}}</em></span></label>
                        <input type="text" class="form-control" id="lname" name="lname" value="{{ old('lname') }}">
                    </div>
                    <div class="form-group">
                        <label>Phone: <span><em>{{$errors->first('phone')}}</em></span></label>
                        <input type="text" class="form-control" id="phone" name="phone" maxlength="10" value="{{ old('phone') }}">
                    </div>
                    <div class="form-group">
                        <label>Email address: <span><em>{{$errors->first('email')}}</em></span></label>
                        <input type="text" class="form-control" id="email" name="email" value="{{ old('email') }}">
                    </div>
                    <div class="form-group">
                        <label>DOB: <span><em>{{$errors->first('dob')}}</em></span></label>
                        <input type="date" class="form-control" id="dob" name="dob" value="{{ old('dob') }}">
                    </div>
                    <div class="form-group">
                        <label>Gender: <span><em>{{$errors->first('gender')}}</em></span></label>
                        <input type="radio" name="gender" value="M" @if(old('gender') == 'M') checked @endif> Male
                        <input type="radio" name="gender" value="F" @if(old('gender') == 'F') checked @endif> Female
                    </div>
                    <div class="form-group">
                        <label>City: <span><em>{{$errors->first('city')}}</em></span></label>
                        <select class="form-control" name="city">
                            <option value="">Select</option>
                            <option value="Guwahati" {{ (old('city') == 'Guwahati') ? 'selected' : '' }}>Guwahati</option>
                            <option value="Kolkata" {{ (old('city') == 'Kolkata') ? 'selected' : '' }}>Kolkata</option>
                            <option value="Delhi" {{ (old('city') == 'Delhi') ? 'selected' : '' }}>Delhi</option>
                        </select>
                    </div>
                    <div class="form-group">
                        <label>Hobbies: <span><em>{{$errors->first('hobbies')}}</em></span></label>
                        <input type="checkbox" name="hobbies[]" value="Cricket" {{ !empty(old('hobbies')) && (in_array('Cricket', old('hobbies'))) ? 'checked' : ''}}> Cricket
                        <input type="checkbox" name="hobbies[]" value="Football" {{ !empty(old('hobbies')) && (in_array('Football', old('hobbies'))) ? 'checked' : ''}}> Football
                        <input type="checkbox" name="hobbies[]" value="Badminton" {{ !empty(old('hobbies')) && (in_array('Badminton', old('hobbies'))) ? 'checked' : ''}}> Badminton
                    </div>
                    <div class="form-group">
                        <label>Photo: <span><em>{{$errors->first('profile_photo')}}</em></span></label>
                        <input type="file" class="form-control" id="profile_photo" name="profile_photo" value="{{ old('profile_pic') }}">
                    </div>
                    <div class="form-group">
                        <label>Password: <span><em>{{$errors->first('password')}}</em></span></label>
                        <input type="password" class="form-control" id="password" name="password" value="">
                    </div>
                    <button type="submit" class="btn btn-primary">Submit</button>
                </form>
            </div>
        </div>
    </div>    
@endsection

@section('script')
    <script type="text/javascript" src="{{ URL::asset('js/registration.js') }}"></script>
@endsection

UserController.php

<?php

namespace App\Http\Controllers;

use App\Http\Requests\ValidateRegistration;

use Illuminate\Support\Facades\Hash;

use Illuminate\Http\Request;

use App\User;

class UserController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        //
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        $title = "Registration";
        return view('/registration', compact('title'));
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(ValidateRegistration $request)
    {
        //dd(request()->all());
        if( !isset($errors) )
        {
            $path = $request->file('profile_photo')->store('uploads');
            $hobbies = '';
            foreach( request('hobbies') as $hobby )
            {
                $hobbies .= $hobby.',';
            }
            $password = Hash::make(request('password'));
            $activationKey = Hash::make(rand());
        }

        User::create([
            'fname'         => request('fname'),
            'lname'         => request('lname'),
            'phone'         => request('phone'),
            'email'         => request('email'),
            'gender'        => request('gender'),
            'city'          => request('city'),
            'hobbies'       => $hobbies,
            'password'      => $password,
            'profile_pic'   => $path,
            'activationKey' => $activationKey
        ]);

        // redirect to home page
        return redirect('/registration-success');

        $data = array();
        $data['status'] = 'success';
        $data['message'] = 'Registration success';
        return response()->json($data);
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        //
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        //
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        //
    }
}

ValidateRegistration.php

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class ValidateRegistration extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'fname'         => 'required',
            'lname'         => 'required',
            'phone'         => 'required|size:10|regex:/^[0-9]+$/i|unique:users,phone',
            'email'         => 'required|regex:/^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/|unique:users,email',
            'gender'        => 'required',
            'profile_photo' => 'required|image',
            'password'      => 'required'
        ];
    }

    /**
    * Get the error messages for the defined validation rules.
    *
    * @return array
    */
    public function messages()
    {
        return [
            'fname.required' => 'Firstname is mandatoy',
            'lname.required'  => 'Lastname is mandatory',
            'phone.required'  => 'Phone is mandatory',
            'phone.size'  => 'Phone must be 10 digit',
            'phone.unique'  => 'Phone number already exist',
            'phone.regex'   => 'Invalid phone',
            'email.required'  => 'Email is mandatory',
            'email.unique'  => 'Email already exist',
            'email.regwx' => 'Invalid email',
            'gender.required'   => 'Please select gender',
            'profile_photo.required'  => 'Profile pic is mandatory',
            'profile_photo.image'     => 'Invalid image',
            'password.required'  => 'Password is mandatory',
        ];
    }
}

registration.js

$(document).ready(function(){
    $('#registrationForm').submit(function(e){
        e.preventDefault();

        formInputs = $('#registrationForm').serialize();
        console.log(formInputs);
        $.ajaxSetup({
            url: "/submitRegistrationData",
            data: formInputs,
            async: true,
            dataType: 'json',
            beforeSend: function () {
            },
            complete: function(){
            }
        });
        $.post()
        .done(function(response) {
            console.log(response);
        })
        .fail(function() {
            console.log('failed');
        })
    });
});


Solution 1:[1]

This is typical validation error. Just check in browser devtools what do you send via ajax and I guess you will easily find a solution what is missing.

Use Network Tab, select XHR and find your request. Look at bottom of headers tab, here should be your data like this - http://joxi.ru/V2VLXKvhxQpN4r

Solution 2:[2]

You might need to add this.

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

Solution 3:[3]

this error is because, your data is not being identified, server side.

You can try with this javascript:

function formDataToJSON(form) {
    let obj = {};
    let formData = form.serialize();
    let formArray = formData.split("&");

    for (inputData of formArray){
        let dataTmp = inputData.split('=');
        obj[dataTmp[0]] = dataTmp[1];
    }
    return JSON.stringify(obj);
}

$(document).ready(function(){
    $('#registrationForm').submit(function(e){
        e.preventDefault();

        let form = $(this);
        let formData = formDataToJSON(form);

        $.ajax({
            type: "POST",
            url: "/submitRegistrationData",
            data: formData, // serializes the form's elements.
            headers : {
                "content-type": "application/json",
                "accept": "application/json",
            },
            success: function(data){
                console.log(data); // show response from the php script.
            },
            error : function(response, textStatus, errorThrown){
                console.log(errorThrown);   
            }
        }); 

    });
});

Solution 4:[4]

I had a similar problem. I had been sending GET request to a POST route.

Solution 5:[5]

I also got the same error 422 and ajax data is not storing

This is my routes

   Route::post('/kyc-form-update', 'KycController@store')->name('kyc-form-update');

And this is my ajax code

 <script type="text/javascript">
    $.ajaxSetup({
        headers: {
            'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
        }
    });

    $('#kycForm').on('submit', function(event) {
        event.preventDefault();

        first_name = $('#first_name').val();
        middle_name = $('#middle_name').val();
        last_name = $('#last_name').val();
        phone_number = $('#phone_number').val();
        email = $('#email').val();
        gender = $('#gender').val();
        nationality = $('#nationality').val();
        occupation = $('#occupation').val();
        dob = $('#dob').val();
        country = $('#country').val();
        province = $('#province').val();
        district = $('#district').val();
        municipility = $('#municipility').val();
        tole = $('#tole').val();
        ward_no = $('#ward_no').val();
        pan_number = $('#pan_number').val();
        document_number = $('#document_number').val();
        document_type = $('#document_type').val();
        citizenship_img_front = $('#citizenship_img_front').val();
        citizenship_img_back = $('#citizenship_img_back').val();
        driving_liscence_img = $('#driving_liscence_img').val();
        passport_img = $('#passport_img').val();
        issued_date = $('#issued_date').val();
        expiry_date = $('#expiry_date').val();
        issued_address = $('#issued_address').val();

        $.ajax({
            url: "/user/kyc-form-update",
            method: "POST",
            type: "POST",
            contentType: "application/json",
            enctype: "multipart/form-data",
            processData: false,
            cache: false,
            data: {
                "_token": "{{ csrf_token() }}",
                first_name: first_name,
                middle_name: middle_name,
                last_name: last_name,
                phone_number: phone_number,
                email: email,
                gender: gender,
                nationality: nationality,
                occupation: occupation,
                dob: dob,
                country: country,
                province: province,
                district: district,
                municipility: municipility,
                tole: tole,
                ward_no: ward_no,
                pan_number: pan_number,
                document_number: document_number,
                document_type: document_type,
                citizenship_img_front: citizenship_img_front,
                citizenship_img_back: citizenship_img_back,
                driving_liscence_img: driving_liscence_img,
                passport_img: passport_img,
                issued_date: issued_date,
                expiry_date: expiry_date,
                issued_address: issued_address,

            },
            success: function(response) {

                console.log(response);
                if (response) {
                    $('#success-message').text(response.success);
                    $("#kycForm")[0].reset();
                }
            },
            error: function(response) {

               
                console.log('failed');
            },
        });
    });
</script>

And here is my controller

  <?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Kyc;


class KycController extends Controller
{
    public function index()
    {
        return view('user.kyc');
    }


    public function store(Request $request)
    {

        $request->validate([
            'first_name' => 'required',
            'middle_name' => '',
            'last_name' => 'required',
            'phone_number' => 'required|numeric',
            'email' => 'required|email|max:255',
            'gender' => 'required',
            'nationality' => 'required',
            'occupation' => 'required',
            'dob' => 'date',
            'country' => 'required',
            'province' => 'required',
            'district' => 'required',
            'municipility' => 'required',
            'tole' => 'required',
            'ward_no' => 'required|numeric',
            'pan_number' => 'numeric',
            'document_number' => 'required|numeric',
            'document_type' => '',
            'citizenship_img_front' => '',
            'citizenship_img_back' => '',
            'driving_liscence_img' => '',
            'passport_img' => 'required',
            'issued_date' => 'date',
            'expiry_date' => 'date',
            'issued_address' => '',

        ]);


        Kyc::create([
            'first_name' => $request->first_name,
            'middle_name' => $request->middle_name,
            'last_name' => $request->last_name,
            'phone_number' => $request->phone_number,
            'email' => $request->email,
            'gender' => $request->gender,
            'nationality' => $request->nationality,
            'occupation' => $request->occupation,
            'dob' => $request->dob,
            'country' => $request->country,
            'province' => $request->province,
            'district' => $request->district,
            'municipility' => $request->municipility,
            'tole' => $request->tole,
            'ward_no' => $request->ward_no,
            'pan_number' => $request->pan_number,
            'document_number' => $request->document_number,
            'document_type' => $request->email,
            'citizenship_img_front' => $request->citizenship_img_front,
            'citizenship_img_back' => $request->citizenship_img_back,
            'driving_liscence_img' => $request->driving_liscence_img,
            'passport_img' => $request->passport_img,
            'issued_date' => $request->issued_date,
            'expiry_date' => $request->expiry_date,
            'issued_address' => $request->email,


        ]);

        //    return response()->json([ 'success'=> 'Form is successfully submitted!']);
        //    return redirect('/kyc-form')->with('success', 'Ajax Form Data Has Been validated and store into database');
    return redirect()->back()->with('message', 'Form is successfully submitted!');

    }

}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 arku
Solution 2 ajthinking
Solution 3 Ivan Fretes
Solution 4 Bob.B
Solution 5 tek bhatt