skip to Main Content

When I send a photo I get a 422 error from axios with message:

The preview must be a file of type: jpg, jpeg, png, pdf.

But I sent the photo in the correct format. I don’t really understand where the error is.

My vue component methods:

data() {
        return {
            name: '',
            description: '',
            preview: '',
        }
    },
    methods: {
        create() {
            this.projectStore.createProject(this.name, this.description, this.preview)
        },
        onFileChange(e) {
            let img = e.target.files[0]
            let reader = new FileReader()
            reader.readAsDataURL(img)
            this.preview = img
        },
    },

My store(Pinia) method:

async createProject(name, description, preview) {
            let formData = new FormData()
            formData.append('preview', preview)
            console.log(formData);
            axios.get('/sacntum/csrf-cookie').then(response => {
                axios.post('api/create', {
                    name: name,
                    description: description,
                    preview: formData,
                }, {
                    headers: {
                        'content-type': 'multipart/form-data',
                    }
                })
                    .then(response => {
                        if (response.data.success) {
                            console.log(response)
                        } else {
                            console.log('response')
                        }
                    })
                    .catch(function (error) {
                        console.error(error)
                    })
            })
        },

My Controller in Laravel:

public function createProject(Request $request)
    {
        if (Auth::check()) {
            $attr = $request->validate([
                'name' => 'required|string|max:255',
                'description' => 'required|string|max:1000',
                'preview' => 'required|mimes:jpg,jpeg,png,pdf|max:2048',
            ]);

            $generated_new_name = time() . '.' . $attr['preview']->getClientOriginalExtension();
            $request->preview->move(public_path('preview_images'), $generated_new_name);

            $project = Project::create([
                'name' => $attr['name'],
                'description' => $attr['description'],
                'preview' => $generated_new_name,
            ]);

            $success = true;
            $message = 'Project created successfully';
        } else {
            $success = false;
            $message = 'You are not logged yet';
        }

        $response = [
            'success' => $success,
            'message' => $message,
        ];

        return response()->json($response);
    }

I tried to make formdata in vue component and then pass to store but it didn’t help

3

Answers


  1. Chosen as BEST ANSWER

    Ok, finally i figured out was wrong. I changed this code in my createProject in my Store.js:

    let formData = new FormData()
            formData.append('preview', preview)
            console.log(formData);
            axios.get('/sacntum/csrf-cookie').then(response => {
                axios.post('api/create', {
                    name: name,
                    description: description,
                    preview: formData,
                }, {
                    headers: {
                        'content-type': 'multipart/form-data',
                    }
                })
    

    To this:

    let formData = new FormData()
            formData.append('name', name)
            formData.append('description', description);
            formData.append('preview', preview)
            console.log(preview);
            axios.get('/sacntum/csrf-cookie').then(response => {
                axios.post('api/create', formData, {
                    headers: {
                        'Content-Type': 'multipart/form-data'
                    }
                })
    

    I passed the formdata object with the photo separately with the other parameters, although I should have put all the parameters in formdata.

    Thanks everyone who tried to help. @Nothingbutageek I think it's not necessary to write custom rules for the photo unless you need some specific validation or specific error response, although if you need specific error response you can use form request validation.


  2. Use the below code in the controller

        $photo = $request->file('image');
        $imagename = time() . '.' . $photo->getClientOriginalExtension();        
        
        // Add Normal Image...
        $destinationPath = public_path('uploads');
        $photo->move($destinationPath, $imagename);
    
        echo '<pre>';
        print_r("Upload Successfully. Store File : laravel_code/public/uploads & laravel_code/public/uploads/thumbnail_images");
    
    Login or Signup to reply.
  3. In order to validate a file on laravel request you will need to write a custom validation.
    https://laravel.com/docs/10.x/validation#custom-validation-rules

    The passes function should be something like this

    public function passes($attribute, $value): bool
    {
        $extension = strtolower($value->getClientOriginalExtension());
    
        return in_array($extension, ["jpg", "jpeg", "png", "pdf"]);
    }
    

    The function above only controls the mime types, you can add whichever validation you wish in this function

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search