chrisgrim
5 months ago
6
6
Vue

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

Posted 5 months ago by chrisgrim

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]);
    }

Please sign in or create an account to participate in this conversation.