mafortis
mafortis

Reputation: 7138

Sending photo with vuejs

I am using ElementUi uploader and i need to send my file with the rest of my form data, but it doesn't seem to send right details of photo to back-end:

Screenshots

Console log when i select an image

one

Data that sent to back-end

two

Code

photo input

<el-upload
    action="#"
    :limit="1"
    :multiple="false"
    :on-change="photoChanged"
    :on-exceed="handleExceed"
    list-type="picture-card"
    :on-remove="handleRemove"
    :on-preview="handlePictureCardPreview"
    :before-remove="beforeRemove"
    :auto-upload="false">
    <i slot="default" class="el-icon-plus"></i>
</el-upload>
<el-dialog :visible.sync="dialogVisible">
    <img width="100%" :src="dialogImageUrl" alt="">
</el-dialog>

Script

export default {
    data() {
        return {
            dialogImageUrl: '',
            dialogVisible: false,
            form: {
                name: '',
                slug: '',
                price: '',
                new_price: '',
                sku: '',
                qty: 1,
                active: '',
                photo: '',
                shortDesc: '',
                longDesc: '',
                region: '',
                date1: '',
                date2: '',
                type: [],
                tags: [],
                brand_id: '',
                categories: [],
                resource: '',
                user_id: ''
            }
        }
    },
    methods: {
        onSubmit(e) { //send data to back-end
            e.preventDefault();
            axios.post('/api/admin/products/store', this.form)
            .then(res => {
                console.log(res);
            })
            .catch(error => {
                console.log(error);
            })
        },
        handleRemove(file) {
            this.form.photo = ''; // remove photo from from when it's removed
        },
        photoChanged(file, fileList){
            this.form.photo = file.raw;  // add photo to form when it's selected
            console.log('file', file) // screenshot 1
            console.log('raw', file.raw) //screenshot 2
        },
        handlePictureCardPreview(file) {
            this.dialogImageUrl = file.url;
            this.dialogVisible = true;
        },
        handleExceed(files, fileList) {
            this.$message.warning(`The limit is 1, you selected ${files.length} files this time, add up to ${files.length + fileList.length} totally, remove old image and try again.`);
        },
        beforeRemove(file) {
            return this.$confirm(`Cancel the transfert of ${ file.name } ?`);
        }
    },
  }
</script>

Any idea?

Upvotes: 0

Views: 2080

Answers (3)

naveenkumar
naveenkumar

Reputation: 318

I have used FormData to send the photo or document to the server. JavaScript FormData

  <form id="myForm" name="myForm">
    <div>
        <label for="username">Enter name:</label>
        <input type="text" id="username" name="username" v-model="imageData.name">
      </div>
     <div>
        <label for="useracc">Enter account number:</label>
        <input type="text" id="useracc" name="useracc" v-model="imageData.account">
      </div>
    <label for="userfile">Upload file:</label>
    <input type="file" id="userfile" name="userfile">
  </div>
  <input type="submit" value="Submit!">
</form>

export default {
    data() {
        return { 
            imageData: {}
        }
    },
    methods: {
        uploadImageToServer() {
            // 1.Save the form Data and return the new id to save the image 
            axios.post('/api/admin/products/store', this.imageData)
            .then(res => {
                if(res.id) {
                //2. Save the image to id
                let formData = new FormData();
                let file = document.getElementById('userfile');
                formData.append('file', file)
                axios.post('/api/admin/products/image/{id}', formData)
                    .then(res => {
                        console.log(res)
                    })
                }
            })
            .catch(err => {
                console.log(err)
            }) 

        }
    }
}

Here, Both form data & file data maynot be send in single requst. 1. Saving the form data and return the id. 2. Saving the image data to the id. Replace the html with 'element-ui' syntax. Ensure that your rest api receives the form data as the input.

Upvotes: 1

mafortis
mafortis

Reputation: 7138

Solved

Well I have decided to give up on sending image with rest of data to backend and upload image first with action="#" in my input and in return i get file name in my form and just send the file name with rest of form instead of sending image file.

<el-upload
  action="/api/upload"
  :on-success="handleAvatarSuccess"
.....>


methods: {
  handleAvatarSuccess(res, file) {
    this.form.photo = res.data;
  },
}

So it sends my file to back-end as soon as it's selected and set the name of stored file in my form.photo and that name will be send with rest of my form inputs.

Hope it could be useful to others as well.

Upvotes: 0

Qonvex620
Qonvex620

Reputation: 3972

convert your file to base64

when you select an image, use code below

       onImageChange() {
          let file = this.form.photo

          if (file == '')
                return;

           this.createImage(file);
       }

       createImage(file) {
           let reader = new FileReader();
           let el = this
           reader.onload = (e) => {
                el.form.photo = e.target.files[0];      
           };
           reader.readAsDataURL(file);
       },

attach onImageChange function in your input file

Upvotes: 1

Related Questions