1

I'm trying to make a POST Request to Laravel from Reactjs to insert into the database a product which may have some categories which is an array, also some images.

But it seems that when I send the POST Request with Content-Type: 'multipart/form-data', the laravel (or php) doesn't JSON Decode the array. Same thing for 'images'

How can I solve this?

This is my custom validation rules:

public function rules(): array
    {
        return [
            'name' => 'required|min:3|max:255',
            'title' => 'required|min:3|max:255',
            'subtitle' => 'required|min:3|max:255',
            'description' => 'nullable|min:10|max:1000',
            'categories' => 'required|array',
            'images' => 'required|array|min:1|max:10',
            'images.*' => 'image|mimes:jpeg,png,jpg,gif|max:2048',
        ];
    }

Reactjs:

const handleUploadPictures = (event) => {
        const files = event.target.files;
        if (!files.length) return toast.error("You need to upload minimum 1 image.");

        setProductImages(Array.from(files));
    };

 const createProduct = async () => {
        const formData = new FormData();
        formData.append("name", productName);
        formData.append("title", productTitle);
        formData.append("subtitle", productSubTitle);
        formData.append("description", productDescription);
        formData.append("categories", JSON.stringify(['sneakers', 'shoes']));
        formData.append("images", JSON.stringify(productImages)); // productImages = Array.from(event.target.files);


        await axios
            .post(`${API_URL}/api/create/product`, formData, {
                headers: {
                    "Content-Type": "multipart/form-data",
                },
            })
            .then((response) => {
                console.log(response.data);
                return response.data;
            })
            .catch((error) => {
                console.log(error);
                return getResponseValidationErrors(error) ?? formatResponseError(error, "We could not add the product.");
            });

    }

I get 422 Unprocessable Content, response is:

{
        "message": "The categories field must be an array. (and 1 more error)",
        "errors": {
            "categories": [
                "The categories field must be an array."
            ],
            "images": [
                "The images field must be an array."
            ]
        }
    }

1 Answer 1

2

The possible options available for you is to create middleware to json_decode the json value in your request data or transform the 'json' value directly in the FormRequest file assuming you're using it you can override the prepareForValidation():

Preparing Input for Validation

Using Form Request

protected function prepareForValidation()
{
    $this->merge([
        'images' => json_decode($this->images),
        'categories' => json_decode($this->categories),
    ]);
}

Using Middleware

class DecodeJsonInput
{
    public function handle(Request $request, Closure $next)
    {
        $request->merge([
            'images' => json_decode($request->input('images')),
            'categories' => json_decode($request->input('categories'))
        ]);

        return $next($request);
    }
}

// Then add it to the route
Route::post('/create/product', [ProductController::class,'store'])->middleware(DecodeJsonInput::class);

PS: I'm not sure if the middleware will work if since I didn't check it yet. But in theory it should work.

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

2 Comments

Thank you! It is working now! I'm using Form Request.
Had a similar problem and followed this article that offers a similar solution also using prepareForValidation that stringifies the non-file payload and then decodes it in the form request

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.