4

I'm making a Laravel API, but I can't seem to send JSON data in one of the posts. I checked the other posts in StackOverflow, but it seems that my JSON request is correct, so I can't seem to find the error:

Here is the code in my Controller's method:

$validator = Validator::make($request->all(), [
    "name" => "required|string",
    "colors" => "json",
     "sizes" => "json"
]);

if($validator->fails())
    return response()->json(["errors" => $validator->errors()], 400);

Here is the request body:

{
 "name": "Test",
 "colors": {
   "Man": "#0000ff",
   "Second": "#FF0000"
 },
 "sizes": {
   "titles": "20px"
 }
}

The error:

{
   "errors": {
       "colors": ["The colors must be a valid JSON string."],
       "text_sizes": ["The text sizes must be a valid JSON string."]
   }
}

What seems to be the problem? Thank you!

5
  • Well you are passing an json object, not an json string. So for this to work I think you need to do JSON.parse(). So that you get something like "\"colors\": {\n \"Man\": \"#0000ff\",\n \"Second\": \"#FF0000\"\n }" Commented Nov 16, 2020 at 15:20
  • I tried doing this: "colors": "{'Main': '#0000ff','Secondary': '#FF0000'}" and it didn't work. Isn't this a valid json string? Commented Nov 16, 2020 at 15:22
  • 1
    No I think you need to use backslashes: "\"colors\": \"Man\": \"#0000ff\",\"Second\": \"#FF0000\" }". PS I meant JSON.stringify() ofcourse. Commented Nov 16, 2020 at 15:27
  • I see. Well, how can I stringify only JSON fields before I validate them? Because I only want in my case, two properties to be JSON data. Commented Nov 16, 2020 at 15:33
  • @Tom Please make a response in the thread so that I can mark my post as answered. Thank you. Commented Nov 16, 2020 at 16:21

3 Answers 3

11

Well you need to pass an JSON String instead of an JSON Object. This can be done either by json_encode or JSON.stringify.

As an answer on your last comment.:

You could either do this in your frontend application with JSON.stringify or you could implement an Form Request with an prepareForValidation(): https://laravel.com/docs/8.x/validation#prepare-input-for-validation.

Where you would do an json_encode() on the json properties. Like:

protected function prepareForValidation()
{
    $this->merge([
        'colors' => json_encode($this->colors),
        'text_sizes' => json_encode($this->text_sizes)
    ]);
}

Or in your case:

$validator = Validator::make($request->merge([
        'colors' => json_encode($request->colors),
        'text_sizes' => json_encode($request->text_sizes)
    ]), [
    "name" => "required|string",
    "colors" => "json",
     "sizes" => "json"
]);
Sign up to request clarification or add additional context in comments.

Comments

1

I found a simple solution, just use double quotes to represent a json string, and escape the double quotes inside the json:

{ "name": "Test", "colors": "{\"Man\": \"#0000ff\",\"Second\": \"#FF0000\"}", "sizes": "{\"titles\": \"20px\"}" }

This solve my issue sending json string from Insomnia Api rest.

Comments

-1

laravel have a convenient way to validate a request please follow these steps to make your own request and response for api 1-php artisan make:request YourRequest

Then customize your request like this

  <?php
    
    namespace App\Http\Requests;
    
    use Illuminate\Contracts\Validation\Validator;
    use Illuminate\Foundation\Http\FormRequest;
    use Illuminate\Http\Exceptions\HttpResponseException;
    use Illuminate\Http\Response;
    
    class OrderRequest extends FormRequest
    {
    
        /**
         * Determine if the user is authorized to make this request.
         *
         * @return bool
         */
        public function authorize(): bool
        {
            return true;
        }
    
        /**
         * Get the validation rules that apply to the request.
         *
         * @return array
         */
        public function rules(): array
        {
    
            $rules = [
                'your filed name' => 'required',
                
            ];
            return $rules;
        }
    
        /**
         * Get the error messages that apply to the request parameters.
         *
         * @return array
         */
        public function messages()
        {
            return [
                'your field name' => 'custom message',
              
            ];
        }
    
        /**
         * Handle a failed validation attempt.
         *
         * @param Validator $validator
         * @return void
         *
         * @throws ValidationException
         */
        protected function failedValidation(Validator $validator)
        {
            $error = collect($validator->errors())->collapse()->toArray();
            $errors = implode(' | ', $error);
            throw new HttpResponseException(response()->json(
                ['response' => ['status' => false, 'message' => $errors]],
                Response::HTTP_UNPROCESSABLE_ENTITY));
        }
    }

this will solve error as recommended by laravel and its a professional way

then use this Request into controller .

if you want to use your own code then

just use json_encode($this->text_sizes)

1 Comment

Thank you, but this seems impractical when I only want two fields to validated instantly. I don't have any complex logic right now, so there is no need for me to make all of this.

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.