WilliamDrake's avatar

Laravel 5.4, AJAX Not Returning Error Properly

Hi all,

I've been trying to follow quite a few different articles on how to deal with AJAX requests in Laravel. They're all different..

I have one that is finally not throwing me a 500 error, but it actually does not throw validation errors in the way you'd think.

My code will always default to the AJAX success part, not the error part, and display a "Success" in the console but also display the error JSON thrown back by my controller.

I have no idea what's going on my dudes. If you could help me out, it would be much appreciated!

My Controller, "BrandsController.php"

public function store(Request $request)
    {
        if ($request->ajax())
        {
            $rules = array(
                "name"      => "required|string|unique:brands|max:255",
                "contact"   => "string|max:255",
                "email"     => "string|max:255",
                "phone"     => "max:12"
            );

            $validator = Validator::make(Input::all(), $rules);

            if ($validator->fails())
            {
                return \Response::json(array(
                    "errors" => $validator->getMessageBag()->toArray()
                ));
            }
            else
            {
                // Submit to the database
                $brand = new Brand();

                $brand->name        = $request->name;
                $brand->contact     = $request->contact;
                $brand->email       = $request->email;
                $brand->phone       = $request->phone;
                $brand->created_by  = auth()->user()->id;
                $brand->updated_by  = auth()->user()->id;

                $brand->save();

                return \Response::json($brand);
            }
        }
        else
        {
            return \Response::json(array("error" => "response was not JSON"));
        }
    }

My Route

// Brands
Route::get('/brands', 'BrandsController@index')->name('brands');
Route::post('/brands/store', 'BrandsController@store');

My AJAX JavaScript (stored as 'create_ajax.js' and called using Html::scripts())

$(document).ready(function() {

    /**
    * Save a new brand to the database via AJAX
    */
    var url = "/brands/store";

    $("#save").click(function (e) {

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

        e.preventDefault();

        var formData = {
            name:       $('#name').val(),
            contact:    $('#contact').val(),
            email:      $('#email').val(),
            phone:      $('#email').val(),
        }

        var type = "POST";

        console.log(formData);

        $.ajax({

            type: type,
            url: url,
            data: formData,
            dataType: 'json',
            success: function (data) {
                console.log(data);
            },
            error: function (data) {
                console.log("Error: ", data);
                console.log("Errors->", data.errors);
            }

        });

    });

});

My HTML (a partial snippet as it is a modal)

<div class="modal" id="modal-create">
    <div class="modal-background" onclick="modal('#modal-create', 'close');"></div>
    <div class="modal-content">
        <div id="modal-create-results"></div>
        <h4 class="title is-4">
            Create a Brand
        </h4>
        <form id="create_brand" name="create_brand" class="form" novalidate="">
            <div class="field is-horizontal">
                {{ Form::label("name", "Name", ["class" => "field-label is-normal"]) }}
                <div class="field-body">
                    <div class="field">
                        <p class="control">
                            {{ Form::text('name', null, ["class" => "input", "id" => "name", "required" => "required", "autofocus" => "autofocus"]) }}
                        </p>
                    </div>
                </div>
            </div>
            <div class="field is-horizontal">
                {{ Form::label("contact", "Contact", ["class" => "field-label is-normal"]) }}
                <div class="field-body">
                    <div class="field">
                        <p class="control">
                            {{ Form::text('contact', null, ["class" => "input", "id" => "contact"]) }}
                        </p>
                    </div>
                </div>
            </div>
            <div class="field is-horizontal">
                {{ Form::label("email", "Email", ["class" => "field-label is-normal"]) }}
                <div class="field-body">
                    <div class="field">
                        <p class="control">
                            {{ Form::email('email', null, ["class" => "input", "id" => "email"]) }}
                        </p>
                    </div>
                </div>
            </div>
            <div class="field is-horizontal">
                {{ Form::label("phone", "Phone", ["class" => "field-label is-normal"]) }}
                <div class="field-body">
                    <div class="field">
                        <p class="control">
                            {{ Form::text('phone', null, ["class" => "input", "id" => "phone"]) }}
                        </p>
                    </div>
                </div>
            </div>
            <div class="field is-horizontal">
                <p class="control is-grouped">
                    {{ Form::button("Save", ["type" => "submit", "class" => "button is-stenton", "id" => "save"]) }}
                    <a class="button" onclick="modal('#modal-create', 'close');">Cancel</a>
                </p>
            </div>
        </form>
    </div>
    <button class="modal-close" onclick="modal('#modal-create', 'close');"></button>
</div>

<meta name="_token" content="{{ csrf_token() }}" />
{{ Html::script('js/brands/create_ajax.js') }}
0 likes
5 replies
Borisu's avatar

I think the correct check if $request->expectsJson()

Try it and come back with results :)

WilliamDrake's avatar
WilliamDrake
OP
Best Answer
Level 1

@Borisu Apparently I needed to send back an error code (422 by default).

:)

This was achieved by both:

$this->validate($request, $rules);

and

$validator = Validator::make(Input::all(), $rules);
if ($validator->fails())  {
    return \Response::json(array("errors" => $validator->getMessageBag()->toArray()), 422);
}
Borisu's avatar

Well glad you solved it :)

1 like

Please or to participate in this conversation.