Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

chrisgrim's avatar

Is it possible to submit an axios post with an image(formData) and variables(data) in Vue

Hi, I have a vue Component

<template>
<div>
  <div>
        <br>
        <h4>Production Company Name</h4>
  </div>
    <div class="autocomplete">
        <input type="text"
        v-model="search"
        @input="onChange"
        @keydown.down="onArrowDown"
        @keydown.up="onArrowUp"
        @keydown.enter.prevent="onEnter" 
        />
            <div 
            v-show="isOpen"
            class="autocomplete-results">
                <div 
                v-for="(result, i) in results"
                :key="i"
                @click="setResult(result)"
                class="autocomplete-result"
                :class="{ 'is-active': i === arrowCounter }"
                >
                    {{ result.organizationName }}
                </div>
            </div>
            <div class="profile-image" :style="{ backgroundImage: 'url(' + organizerImage + ')' }">
                
            </div>
           
            <div id="New Organizer" v-if="isNew">
                <div>
                        <label class="imgclick" :style="{ backgroundImage: 'url(' + avatar + ')' }">
                            <image-upload name="avatar" @loaded="onLoad"></image-upload>
                        </label>
                </div>
                <div>
                    <input type="text" v-model="description" placeholder="Description of Production Company">
                </div>
                <div>
                    <input type="text" v-model="organizerWebsite" placeholder="Enter Production Website">
                </div>
                <div>
                    <input type="text" v-model="twitter" placeholder="enter twitter handle">
                </div>
                <div>
                    <input type="text" v-model="facebook" placeholder="enter facebook handle">
                </div>
                <div>
                    <input type="text" v-model="instagram" placeholder="enter instagram handle">
                </div>
                
      
            </div>

            <div id="Exisiting Organizer" v-if="exists">
                <div >
                    <div>
                        <br>
                        <h4>Organization Description</h4>
                    </div>
                    <div>
                        {{ description }}
                    </div>
                    <div>
                        facebook:
                        {{ facebook }}
                    </div>
                    <div>
                        instgram:
                        {{ instagram }}
                    </div>
                    <div>
                        twitter:
                        {{ twitter }}
                    </div>
                    <div>
                        Website:
                        <br>
                        {{ organizerWebsite }}
                    </div>
                </div>
            </div>
        </div>
        <div class="">
            <button type="submit" class="create" @click.prevent="create"> Save and Continue </button>
        </div>
    </div>
    
  
</template>

<script>
    import ImageUpload from './imageupload.vue';
    export default {

    components: { 
        ImageUpload 
    },
    
    props: {
        items: {
            type: Array,
        },
        event: {
            type: Object,
        }
    },
    
    data() {
        return {
            search: '',
            description: '',
            twitter: '',
            facebook: '',
            instagram: '',
            results: [],
            isOpen:false,
            isNew:false,
            exists:false,
            arrowCounter: -1,
            result:'',
            organizationId: this.event.organizer_id,
            organizerImage:'',
            organizerWebsite:'',
            avatar: '',
        };
    },

    computed: {
        existingOrganization() {
            return this.items[this.event.organizer_id - 1];
        }

    },
    

    methods: {
        onLoad(avatar) {
                this.avatar = avatar.src;
        },
        create() {
            var data = {
                'organizationName': this.search,
                'organizationDescription': this.description,
                'facebookHandle': this.facebook,
                'instagramHandle': this.instagram,
                'twitterHandle': this.twitter,
                'organizationWebsite': this.organizerWebsite,
            };
            //this is image I want to add to data
            formData.append('avatar', this.avatar);

            axios.post('/create-your-event/' + this.event.slug + '/organizer', data).catch(error => {
                module.status = error.response.data.status;
            });
        },

        onArrowDown() {
          if (this.arrowCounter < this.results.length) {
            this.arrowCounter = this.arrowCounter + 1;
          }
        },
        onArrowUp() {
          if (this.arrowCounter > 0) {
            this.arrowCounter = this.arrowCounter - 1;
          }
        },
        onEnter() {
            this.result = this.results[this.arrowCounter];
            this.search = this.result.organizationName;
            this.organizationId = this.result.id;
            this.description = this.result.organizationDescription;
            this.isOpen = false;
            this.exists = true;
            this.isNew = false;
            this.arrowCounter = -1;
            this.facebook = this.result.facebookHandle;
            this.instagram = this.result.instagramHandle;
            this.twitter = this.result.twitterHandle;
            this.organizerWebsite = this.result.organizationWebsite;
            this.organizerImage = '/storage/' + this.result.organizationImagePath;
        },
        setResult(result) {
            this.search = result.organizationName;
            this.description = result.organizationDescription;
            this.organizationId = result.id;
            this.isOpen = false;
            this.exists = true;
            this.isNew = false;
            this.result = result;
            this.facebook = result.facebookHandle;
            this.instagram = result.instagramHandle;
            this.twitter = result.twitterHandle;
            this.organizerWebsite = result.organizationWebsite;
            this.organizerImage = '/storage/' + result.organizationImagePath;
        },
        onChange() {
            this.isOpen = true;
            this.filterResults();
            this.exists = false;
            this.isNew = true;
            this.description = '';
            this.organizationId = '';
            this.facebook = '';
            this.instagram = '';
            this.twitter = '';
            this.organizerImage = '';
            this.organizerWebsite = '';

        },
        filterResults() {
            this.results = this.items.filter(item => item.organizationName.toLowerCase().indexOf(this.search.toLowerCase()) > -1);
        },
        init() {
            if( this.organizationId !== null ) {   
                this.search = this.event.organizer.organizationName;
                this.description = this.event.organizer.organizationDescription;
                this.facebook = this.event.organizer.facebookHandle;
                this.instagram = this.event.organizer.instagramHandle;
                this.twitter = this.event.organizer.twitterHandle;
                this.organizerImage = '/storage/' + this.event.organizer.organizationImagePath;
                this.organizerWebsite = this.event.organizer.organizationWebsite;
                this.exists = true;
                this.avatar = this.event.organizer.organizationImagePath;
            } 
        }
    },
    mounted() {
        this.init()
    },
};
</script>

Everything was working great until I tried to add an image upload to my axios post in the create() method. I click and upload the image and in chrome vue dev tool I can see under avatar it has

avatar:"data:image/jpeg;base64,/9j/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP/sABFEdWNreQABAAQAAAAlAAD/4QMzaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIe Goes on forever

I tried to originally submit using

var data = {
                'organizationName': this.search,
                'organizationDescription': this.description,
                'facebookHandle': this.facebook,
                'instagramHandle': this.instagram,
                'twitterHandle': this.twitter,
                'organizationWebsite': this.organizerWebsite,
        'avatar': this.avatar
            };
axios.post('/create-your-event/' + this.event.slug + '/organizer', data).catch(error => {
                module.status = error.response.data.status;
            });

but it was giving me the error null on store() method. I read that I needed to use formData but when I tried to append() like I have it now I am still getting an error.

Is it possible to send both formData (image) and data (variables) through my axios post? If so, what would the code look like? Thanks!

My controller looks like this

public function storeOrganizer(Request $request, Event $event, Organizer $organizer)
    {
        $organizer = organizer::firstOrNew(request()->validate([
            'organizationName' => 'required',
            'organizationDescription' => 'required',
            'instagramHandle' => '',
            'twitterHandle' => '',
            'facebookHandle' => '',
            'organizationWebsite' => '',
        ]) + ['slug'=> str_slug(request('organizationName'))]);

        $path = $request->file('avatar')->store('organizers', 'public');
  
        $organizer->fill(['user_id'=> auth()->id()]);

        $organizer->save();

        $event->update(['organizer_id' => $organizer->id]);
    }
0 likes
6 replies
bobbybouwmann's avatar

There are two important things here! You need to get the file using the refs in general! Maybe a v-model works as well, but not sure though!

this.file = this.$refs.file.files[0];

The second thing is that you need to post with the correct headers

axios.post( '/single-file',
    formData,
    {
        headers: {
            'Content-Type': 'multipart/form-data'
        }
    }
).then(fucntion () {
    // Success :D
});

You can read more about it here: https://serversideup.net/uploading-files-vuejs-axios/

chrisgrim's avatar

hi @bobbybouwmann

I actually have no trouble uploading the file if all I send is a single file. I can setup

methods: {
            onLoad(avatar) {
                this.avatar = avatar.src;
                this.persist(avatar.file);
            },

            persist(avatar) {
                let data = new FormData();

                data.append('avatar', avatar)
                axios.post(`/user`, data)
                    .then(() => flash('Avatar uploaded!'));
            }
        }

and it works. The issue I am having is I need to create the model for the organization at the same time. If I just upload the image I have nowhere to store the image path because no organization exists. So I need to send my data and the image in the same axios post.

Sabonzy's avatar
Sabonzy
Best Answer
Level 9

You have to add the relevant data to the formData.

methods: {
            onLoad(avatar) {
                this.avatar = avatar.src;
                this.persist(avatar.file);
            },

            persist(avatar) {
                let data = new FormData();

                data.append('avatar', avatar)
                data.append('organizationName',this.organizationName)
// add all relevant ones here before posting to the backend
                axios.post(`/user`,
             data,
            {
                     headers: {
                         'Content-Type': 'multipart/form-data'
                        }
            }
).then(() => flash('Avatar uploaded!'));
bobbybouwmann's avatar

@chrisgrim To let the backend parse the uploaded files you need to set the correct headers in the form, otherwise you get the wrong format back in your backend!

chrisgrim's avatar

Hi Guys!

Thank you so much for all of your help so far. I have got it working with this code

onLoad(avatar) {
                this.avatar = avatar.src;
                this.create(avatar.file);
        },
        create(avatar) {
            let data = new FormData();
            //this is image I want to add to data
            data.append('avatar', avatar)
            data.append('organizationName',this.search)
            data.append('organizationDescription',this.description)

            axios.post('/create-your-event/' + this.event.slug + '/organizer', data,
            {
                    headers: {
                        'Content-Type': 'multipart/form-data'
                    }
            }
                ).catch(error => {
                module.status = error.response.data.status;
            });
        },

The issue is if the user doesn't add the description before adding the image (which calls the method onLoad()) then I get an error because I require the image. I see now that the reason I was getting the error is because of this line

 this.create(avatar.file);

I guess before I was not passing the file through to the create() method. I tried

onLoad(avatar) {
                this.avatar = avatar.src;
        },
        create() {
    
            let data = new FormData();
            //this is image I want to add to data
            data.append('avatar', this.avatar.file)
            data.append('organizationName',this.search)
            data.append('organizationDescription',this.description)

            axios.post('/create-your-event/' + this.event.slug + '/organizer', data,
            {
                    headers: {
                        'Content-Type': 'multipart/form-data'
                    }
            }
                ).catch(error => {
                module.status = error.response.data.status;
            });
        },

where I removed it from the onload() and added it todata.append('avatar', this.avatar.file). But this doesnt work. Is there a way I can just call the create() method and get the same result?

chrisgrim's avatar

Ok I figured it out! in my onLoad method I assigned the file to a data item I created called file

onLoad(avatar) {
                this.avatar = avatar.src;
                this.file = avatar.file;
        },

This way when I submit the form later on I can just assign this.file to the append. Thanks you guys!

Please or to participate in this conversation.