1
votes

In @vue/cli 4.1.1 app I use bootstrap-vue and b-form-file conponent for images uploading

https://bootstrap-vue.js.org/docs/components/form-file/#multiple-files

with definition :

<b-form-file
    id="upload_ad_image"
    v-model="new_upload_ad_image"
    :state="Boolean(new_upload_ad_image)"
    placeholder="Choose a file or drop it here..."
    drop-placeholder="Drop file here..."
    accept="image/jpeg, image/png, image/gif"
></b-form-file>

<div ref="uploaded_img_preview" id="uploaded_img_preview" class="m-2" >Uploaded image preview :</div>

I found snippet https://codepen.io/Tenderfeel/pen/rgqWXR and using it I show selected file on my form for preview. Next I need to upload it on the server. I have an expierence of uploading image as blog using code like :

fetch(this.taskRow.imageFile.blob).then(function (response) {
    if (response.ok) {
        return response.blob().then(function (imageBlob) {
            let imageUploadData = new FormData()
            imageUploadData.append('id', self.taskRow.id)
            imageUploadData.append('image', imageBlob)
            imageUploadData.append('image_filename', self.taskRow.imageFile.name)

But I need to convert uploading image to blob. I use method when image is selected: But got error : Error in callback for watcher "new_upload_ad_image": "InvalidStateError: Failed to execute 'readAsDataURL' on 'FileReader': The object is already busy reading Blobs

watch: {
    new_upload_ad_image(val) {
        if (!val) return;
        if (this.previewImg) {
            this.previewImg.remove();
        }
        const img = document.createElement("img");
        img.classList.add("obj");
        img.file = this.new_upload_ad_image;
        console.log('img.file::')
        console.log(img.file)

        this.previewImg = img;
        console.log('this.$refs.uploaded_img_preview::')
        console.log(this.$refs.uploaded_img_preview)

        console.log('img::')
        console.log(img)

        this.$refs.uploaded_img_preview.appendChild(img);

        const fileReader = new FileReader();
        fileReader.onload = (e) => {
            this.previewImg.src = e.target.result;
        };
        fileReader.readAsDataURL(this.new_upload_ad_image);
        console.log('fileReader::')
        console.log(fileReader)

        let blobObj= fileReader.readAsDataURL(img.file) // RAISE ERROR :

        console.log('blobObj::')
        console.log(blobObj)

    }
},

What I see in the console : https://imgur.com/a/2EZxq9C

How to get blob and upload it on server?

MODIFIED BLOCK :

having file input with id="upload_ad_image" defined :

<b-form-file
    id="upload_ad_image"
    v-model="new_upload_ad_image"
    :state="Boolean(new_upload_ad_image)"
    placeholder="Choose a file or drop it here..."
    drop-placeholder="Drop file here..."
    accept="image/jpeg, image/png, image/gif"
></b-form-file>

I run fetch and see that image blob is invalid and file is created, but it is invalid I have :

var self = this
const upload_ad_image = document.getElementById('upload_ad_image')
console.log('upload_ad_image::')
console.log(upload_ad_image)
console.log('upload_ad_image.files::')
console.log(upload_ad_image.files[0])

if (typeof upload_ad_image.files[0] == 'undefined') {
    self.showPopupMessage('Ad image upload', 'Invalid image !', 'warn')
    return
}
fetch(upload_ad_image.files[0].blob).then(function (response) {
    if (response.ok) {
        return response.blob().then(function (imageBlob) {
            console.log('imageBlob::')
            console.log(imageBlob) // Looks like this var has invalid content(printscreen below)!

            let imageUploadData = new FormData()
            imageUploadData.append('ad_id', self.editableAd.id)
            imageUploadData.append('main', self.new_upload_ad_image_main)
            imageUploadData.append('info', self.new_upload_ad_image_info)
            imageUploadData.append('image', imageBlob)
            imageUploadData.append('image_filename', upload_ad_image.files[0].name)

I see in console : https://imgur.com/a/4ees55C

What is wrong and how it can be fixed ?

"bootstrap-vue": "^2.3.0",
"vue": "^2.6.11",

Thanks!

1
I still search for decision. Have anybody such uploading ?Petro Gromovo

1 Answers

2
votes

File objects do inherit from the Blob interface.

All you can do with a Blob, you can also do it with a File, so in your code you can directly append this.new_upload_ad_image to your FormData.

const inp = document.getElementById('inp');
inp.onchange = (evt) => {
  const formData = new FormData();
  formData.append( 'my-file', inp.files[0], 'file.ext' );
  //  check it's correctly in the FormData
  console.log( [...formData.entries()] );
};
<input type="file" id="inp">