0

I'm trying to validate form data on the backend with Laravel and Vue, but I'm not getting the 422 response.

This is in my controller function:

$this->validate($request, [
    'name' => 'required',
    'city' => 'required',
    'state' => 'required'
    ]);

    $location = $request->isMethod('put') ? 
    Locations::findOrFail($request->id) : new Locations;

    $location->id = $request->input('id');
    $location->name = $request->input('name');
    $location->address = $request->input('address');
    $location->city = $request->input('city');
    $location->state = $request->input('state');
    $location->zip = $request->input('zip');
    $location->phone = $request->input('phone');

    if($location->save())
    {
        return new LocationsResource($location);
    }

Here is the Vue method:

addLocation() {
if (this.edit === false) {
        // Add
        fetch('api/location', {
          method: 'post',
          body: JSON.stringify(this.location),
          headers: {
            'content-type': 'application/json'
          }
        })
          .then(res => res.json())
          .then(data => {
            this.clearForm();
            alert('Location Added');
            this.fetchArticles();
          });

      } else {
        // Update
        fetch('api/location', {
          method: 'put',
          body: JSON.stringify(this.location),
          headers: {
            'content-type': 'application/json'
          }
        })
          .then(res => res.json())
          .then(data => {
            this.clearForm();
            alert('Locations Updated');
            this.fetchArticles();
          })

      }
      }

Here is the form:

<form @submit.prevent="addLocation" class="mb-3">
  <div class="form-group">
    <input type="text" class="form-control" placeholder="Name" v-model="location.name">
    <input type="text" class="form-control" placeholder="City" v-model="location.city">
    <input type="text" class="form-control" placeholder="State" v-model="location.state">
  </div>

  <button type="submit" class="btn btn-light btn-block">Save</button>
</form>

When I open up the inspector and go into Network->XHR I get all the correct status codes back for CRUD, however when the form is supposed to fail I do not get back 422 HTTP status code. When I submit the form with no data, it doesnt save, but no status code gets sent, there is no response to give feedback to the user. Thanks for the help.

3
  • what does your response say in XHR? Commented Oct 4, 2018 at 17:38
  • When I click save and intentionally fail validation, nothing happens, I get no response, no feedback. Commented Oct 4, 2018 at 18:18
  • how could you say 'validation fails' if there is no response? Commented Oct 4, 2018 at 18:19

3 Answers 3

3

I had to add "accept": "application/json" to the header of the addLocation method.

Sign up to request clarification or add additional context in comments.

Comments

1
$this->validate($request, [
    'name' => 'required',
    'city' => 'required',
    'state' => 'required'
    ]);

I've never seen such usage. I don't think controller have the validate function. Try this:

$request->validate([
    'name' => 'required',
    'city' => 'required',
    'state' => 'required'
    ]);

4 Comments

I just checked and yes there is a usage like that coming from ValidateRequest trait but there is no any exception thrown at that function. It just returns an array of unvalidated fields. See; laravel.com/api/5.5/Illuminate/Foundation/Validation/…
I made the change but still same result. Actually I do get a status of 302, type text/html when I click save. Shouldnt I get 422? Does it have anything to do with v-model="location.name" on the form but I only reference "name" in the controller?
and that is probably because of adding id field to new model instance. do not use any id modificaiton in your laravel model instance, let framework handle itself. i mean, use the id just for findOrFail method.
Can you clone this project and try to add backend validation to it? github.com/bradtraversy/larticles_vue_app I tried and get a 302 instead of 422
0

The following code what i have tried

 const form_data = new FormData(document.querySelector('#form_data'));
 fetch("{{route('url')}}", {
       'method': 'post',
       body: form_data,
 }).then(async response => {
      if (response.ok) {
         window.location.reload();
      }
      const errors = await response.json();
      var html = '<ul>';
      for (let [key, error] of Object.entries(errors)) {
          for (e in error) {
              html += `<li>${error[e]}</li>`;
          }
      }
      html += '</ul>';
      //append html to some div

      throw new Error("error");
  })
  .catch((error) => {
     console.log(error)
  });

Controller

use Illuminate\Support\Facades\Validator;//Use at top of the page
$rules = [
    'file' => 'image|mimes:jpeg,png,jpg|max:1024',
    'field1' => 'required',
    'field2' => 'required'
   ];
$validator = Validator::make($request->post(), $rules);
if ($validator->fails()) {
   return response()->json($validator->errors(), 400);
}
session()->flash('flahs', ['status' => 'status', 'message' => 'message']);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.