Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

MrRobot21's avatar

How to return validation errors as JSON to view

Hi awesome people

i'm building an API, i'm validating the input fields in my StoreLesson.php

    public function rules()
    {
        return [
            'title' => 'required',
            'body' => 'required',
        ];
    }

i'm using postman to test the API, things are working fine but when i send POST request with empty fields in postman console in webview i'm getting redirected to welcom.blade.php

//LessonController.php
    public function store(StoreLessons $request) 
    {
        Lesson::create($request->all());

        return response()->json($validator->errors(), 422);  //i'm not getting any json with errors

        //Lesson::create(input::all());

        return $this->respondCreated('Lesson created successfully');
    }

i want to display the validator error as json

thank You

0 likes
21 replies
JoshMountain's avatar

I believe if you submit an Ajax request you will get a JSON response automatically.

Maybe something like this would be appropriate based on your example:

$validator = \Validator::make($request->all(), $this->rules());

if ($validator->fails()) {
   return response()->json($validator->errors(), 422)
}
1 like
MrRobot21's avatar

@JoshMountain thank you so much for you time i really appreciate it

i followed as you mentioned

    public function store(StoreLessons $request) 
    {
        Lesson::create($request->all());

        $validator = \Validator::make($request->all(), $this->rules());

        if ($validator->fails()) {
           return response()->json($validator->errors(), 422);
        }

        return $this->respondCreated('Lesson created successfully');
    }

but when i did POST method without data i was redirected to welcome.blade.php with status code 200 ok.

but when i tried to POST with data i'm getting this error

BadMethodCallException in Controller.php line 82:
Method [rules] does not exist.

thank you

JoshMountain's avatar

@MrRobot21 You want to run the Validator before you create the lesson. I was just assuming the rules method was in the same class, but you can change $this->rules to your array of validation rules you had in your rules() method posted earlier like this.

public function store(StoreLessons $request) 
{
    $validator = \Validator::make($request->all(), ['title' => 'required', 'body' => 'required']);

    if ($validator->fails()) {
       return response()->json($validator->errors(), 422);
    }

    Lesson::create($request->all());

    return $this->respondCreated('Lesson created successfully');
}
MrRobot21's avatar

@JoshMountain thank you so much

every thing seems to be fine but still i'm getting redirected to laravel home page

JoshMountain's avatar

So still no JSON response? Are you sure the route you are hitting is going to the store() method?

MrRobot21's avatar

@JoshMountain yes sir the routes are fine, but still no json, getting redirected to home page

i did go through some stackoverflow posts may have same issue and the solution is as you said above

thank you

MrRobot21's avatar

i changed my controller code to

    //add a new lesson to lessons table
    public function store(StoreLessons $request) 
    {
        $validator = Validator::make($data, $rules);
        
        if ($validator->fails()) {
            return response()->json($validator);
        }

        Lesson::create($request->all());

        return $this->respondCreated('Lesson created successfully');
    }

now there is message

Deprecated: Automatically populating $HTTP_RAW_POST_DATA is deprecated and will be removed in a future version. To avoid this warning set 'always_populate_raw_post_data' to '-1' in php.ini and use the php://input stream instead. in Unknown on line 0

Warning: Cannot modify header information - headers already sent in Unknown on line 0
Redirecting to http://localhost:8000.

thank you

jekinney's avatar

If validation fails and it's an ajax call, it sends the errors as json already. In your fail handler in your consumer of the API it will be available in json.

Even if your not using vue, the same principle applies https://laracasts.com/series/learn-vue-2-step-by-step

Look at the class videos Jeffery handles errors

1 like
MrRobot21's avatar

@jekinney thank you for your time

if validation fails i'm not getting any response at all, just redirecting to home page

if all the fields are not empty the data is inserting to database

larafever's avatar
Level 3

  //add a new lesson to lessons table
    public function store(StoreLessons $request) 
    {
        $validator = Validator::make($data, $rules);
        
        if ($validator->fails()) {
    
    //pass validator errors as errors object for ajax response

          return response()->json(['errors'=>$validator->errors()]);
        }
    
    else{
        Lesson::create($request->all());
        return $this->respondCreated('Lesson created successfully');
    }
    }

So on client side you can get errors object by:


//after ajax done

$.ajax().done(function(response){
    //check if response has errors object
    if(response.errors){

    // do what you want with errors, 

    }
});

Hope it helps

14 likes
amitshahc's avatar

@larafever This should not be the solution. currently I faced same issue. In my local the validation error with json response 2nd param as 422 working and giving json response fine by postman. but the same scenario throws html page even with the Accept: application/json header and Content-type: . If for the 422 error also if I return the 2nd param as 200 then fine. but it should not be the ideal fix. There must be some server to server configuration that forces/overwrites the response type in case of error.

Snapey's avatar

@amitshahc no, no such configuration is required. Just need to let the framework know that you need json response using the Accept header.

MrRobot21's avatar

@larafever thanks for your time

if validation not fails i'm getting this error

ErrorException in LessonsController.php line 49:
Undefined variable: data

thank you.

larafever's avatar

@MrRobot21, can you embed your code for this method


 respondCreated();

I can suggest this looking at your code logic

//I created a new respondCreated Method

public function respondCreated($message)
    {
     //if you to return message to view or ajax process
     return response()->json(['message'=>$message]);
     //Pass message parameter as message  for ajax

     //or anything with message

     
    }

  //add a new lesson to lessons table
    public function store(StoreLessons $request) 
    {
        $validator = Validator::make($data, $rules);
        
        if ($validator->fails()) {
    
    //pass validator errors as errors object for ajax response

          return response()->json(['errors'=>$validator->errors()]);
        }
    
    else{
        Lesson::create($request->all());
    
    // call respondCreated and pass message
        return $this->respondCreated('Lesson created successfully');
    }
    }

Embed your code at line 49 and let's see what's happening

NicoDevs's avatar

Make sure to set the X-Requested-With to XMLHttpRequest when working with Postman. Otherwise, Laravel won't recognize the call as an AJAX request.

11 likes
eugenefvdm's avatar

Thank you @NicoDevs I believe your answer is the correct one when working with Postman. For those novices like myself the X-Requested-With setting and XMLHttpRequest value must be added to request Headers in Postman.

1 like
Sarluk's avatar

if it's actual problem. Laravel send validation error messages for inputs in response by default. If you output error in console.dir() in axios catch callback you'll see an object with response data. To access validation error messages just wirte:

axios({
    method: 'post',
    url: '/site',
    data: form,
    config: { 
        headers: {
            'Content-Type': 'multipart/form-data'
        }
     }
 })
 .catch(function(error){
     console.dir(error.response.data.errors);
  })

1 like
Rohrig's avatar

@nicodevs Thanks! This should be noted in the docs for those doing vanilla js XMLHttpRequests.

Please or to participate in this conversation.