Skip to content
Advertisement

VueJS Laravel – Uploading image using Axios post error: ‘The given data was invalid’

For school I’m making a blog with some people and now I want to upload an image to the blog post. But then this uploading the post the error:

{message: “The given data was invalid.”, errors: {image: [“The image field is required.”]}} errors: {image: [“The image field is required.”]} message: “The given data was invalid.”

I have searched on the internet and looked at other conversations, but I can’t find my solution. Here are my codes:

This is the form in a VueJS component:

<form method="post" action="./api/post" @submit.prevent="createPost()" enctype="multipart/form-data">
    <p>Titel van de post</p>
    <input type="text" placeholder="Titel van de post" name="title" v-model="title">
    <p>Beschrijving bij de post</p>
    <textarea placeholder="Beschrijving bij de post" name="description" v-model="description"/>
    <input type="file" id="image" name="image" ref="image" v-on:change="(e) => {this.onChangeFileUpload(e)}"/>
    <div class="uploadtimer">
        <p>Selecteer een tijd wanneer de post moet worden getoond. (Niet verplicht)</p>
        <datetime format="YYYY-MM-DD H:i" v-model="uploadTime"></datetime>
    </div>
    <input type="submit" class="input-submit">
</form>

The script in the component:

<script>
import datetime from 'vuejs-datetimepicker';

export default {
    components: { datetime },
    data() {
        return {
            title: '',
            description: '',
            uploadTime: '',
            image: '',
        }
    },

    methods: {
        onChangeFileUpload(e) {
            this.image = e.target.files[0];
        },
        createPost() {
            let data = new FormData;
            data.append('image', this.image);

            axios.post('./api/post', {
                title: this.title,
                description: this.description,
                data,
                uploadTime: this.uploadTime,

            }).then(response => {

            }).catch(response => {
                document.getElementById('errorMSG').style.display = 'flex';
                document.getElementById('errorMSG').innerHTML = '<span>!</span><p>Er is iets mis gegaan met het plaatsen van de post.</p>';
                setTimeout(function() {
                    document.getElementById('errorMSG').style.display = 'none';
                }, 5000);
            });


        }
    },
}

And the Controller function I’m using:

public function store(Request $request)
{
    if(Auth::check()) {

        $this->validate($request, [
            'image' => 'required|image|mimes:jpeg,png,jpg,gif,svg',
        ]);

        $post = new Post();
        $post->title = $request->input('title');
        $post->description = $request->input('description');

        $image = $request->file('image');

        $imageExtension = $image->getClientOriginalExtension();
        $imageName = time() . '_' . $imageExtension;

        $image->move(public_path('/imgs/users-avatars/'), $imageName);

        $post->image = '/imgs/posts-images/' . $imageName;

        $post->uploadTime = $request->input('uploadTime');
        $post->user_id = Auth::User()->id;

        $post->save();

        return (['message' => 'succes']);
    } else {
        return (['message' => 'error', 'handler' => 'Authenticated user is required!']);
    }
}

How can I fix this?

Advertisement

Answer

You may use either image rule (that validates a file to be jpeg, png, bmp, gif, svg, or webp) or use mimes:jpeg,png,jpg,gif,svg:

So your validation would be either:

'image' => 'required|file|mimes:jpeg,png,jpg,gif,svg|max:2048',

Or:

'image' => 'required|file|image|max:2048',

Additionally, the file rule checks if the field is a successfully uploaded file and max:2048 rule checks if the file size is less than or equal to 2048 kilobytes (2MB). See Laravel docs for more info.

On VueJs, you have to append all your inputs to a FormData:

let data = new FormData;
data.append('image', this.image);
data.append('title', this.title);
data.append('description', this.description);
data.append('uploadTime', this.uploadTime);

axios.post('./api/post', data)
    .then(
    //...
User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement