简体   繁体   中英

Laravel 5.4, AJAX Not Erroring When it Should

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!

Controller

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

Route

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

AJAX (Embedded via {{ Html::script() }})

$(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);
            }

        });

    });

});

HTML (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') }}

The response is always a success because you always send a successful response, even when it has errors included.

You have three choices in what to do:

1) Send the error code manually

$validator = Validator::make(Input::all(), $rules);
if ($validator->fails())  {
    //422 is the standard error code laravel uses for validation errors so we're going to keep it
    return \Response::json(array("errors" => $validator->getMessageBag()->toArray()),422);
}

2) Let laravel handle it (recommended)

$this->validate($request,$rules); //Laravel will generate the appropriate error exception response

* $this->validate comes from the trait ValidatesRequests

3) Not recommended: keep the controller code as is and change your AJAX code to:

 $.ajax({

        type: type,
        url: url,
        data: formData,
        dataType: 'json',
        success: function (data) {
            if (data.errors) { /* errors happened */ } 
            else { /* no errors happened */ }
        }
 });

Not recommended because handling errors in a success handler is just wrong.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM