jgravois's avatar

FormData Object not receiving file

I am trying to create an avatar editor following the Build a Forum video series.

I am on Laravel 5.8.34.

The console.log in the method #handleFileUpload(e)# shows the file uploaded.

The uploaded image appears on the page.

The console.log in the method #persist(file)# shows an empty object.

DATA FormData {}

The upload does not persist.

My Controller Method:

public function avatar_upload($id)
    {
        $validate = request()->validate([
            'avatar' => ['required', 'image']
        ]);

        $emp = Employee::with('user')->where('user_id', $id)->first();
        $avatar = $emp->user->firstName . $emp->user->lastName . '.png';

        Storage::disk('spaces')
            ->putFileAs('avatars', request()->file('avatar'), $avatar, 'public');

        $emp->avatar = $avatar;
        $emp->save();

        return response([], 204);
    } // end function

My Component:

<template>
    <div>
        <div class="text-center mb-4">

            <div class="flex justify-center font-thin text-grey-dark text-2xl">
                {{user.office}}
            </div>

            <div class="text-center">
                <img class="relative rounded-lg"
                    :src="avatar">
            </div>
            <form @submit.prevent="handleFileUpload"
                  enctype="multipart/form-data"
                  v-if="canEdit">
                <input
                    type="file"
                    name="avatar"
                    ref="file"
                    accept="image/png"
                    class="tw-input"
                    @change="handleFileUpload">
            </form>
        </div>
    </div>
</template>

<script type="text/babel">
    export default {
        name: 'AvatarReplace',
        data() {
            return {
                canEdit: true,
                avatar: this.user.avatar
            };
        },
        props: ['user'],
        methods: {
            handleFileUpload(e) {
                if(! e.target.files.length) { return; } // end if

                let file = e.target.files[0];
                console.log('FILE', file);

                let reader = new FileReader();

                reader.readAsDataURL(file);

                reader.onload = e => {
                  this.avatar = e.target.result;
                };

                this.persist(file);
            },
            persist(file) {
                let data = new FormData();

                data.append('avatar', file);
                console.log('DATA', data);

                let path = `/api/staff/avatar_upload/${this.user.id}`;
                axios.post(path, data)
                    .then((rsp) => {
                        //console.log(rsp);
                        //this.$toastr.s('File Uploaded');
                    });

            }
        }
    };
</script>

0 likes
3 replies
Nakov's avatar

@jgravois on your form you've got the enctype but you are not making a normal form submission but rather using AJAX.. so you might need to tell axios that as well.. something like this:

axios.post(path, data, {
    headers: {
      'Content-Type': 'multipart/form-data'
    }
}).then((rsp) => {
    //console.log(rsp);
    //this.$toastr.s('File Uploaded');
});

Let me know if it works :)

jgravois's avatar

Definitely moving in the right direction ... Changed the error!

Not sure about the new errors though because @JeffreyWay certainly didn't have them

Error: attribute y: Expected length, "NaN".

Error: attribute height: Expected length, "NaN".

Error: attribute y: Expected length, "NaN".

Error: attribute height: Expected length, "NaN".

Error: attribute y: Expected length, "NaN".

Error: attribute height: Expected length, "NaN".

Error: attribute y: Expected length, "NaN".

Error: attribute height: Expected length, "NaN".

Back to Google!

Thanks!!!

MaverickChan's avatar

you should pass avatar's src and file together.


this.avatar = e.target.result // this means the src

data.append should contain both src and file

Please or to participate in this conversation.