1

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://i.sstatic.net/o6s0g.jpg

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://i.sstatic.net/f62Yw.jpg

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 ? Commented Feb 25, 2020 at 4:55

1 Answer 1

2
+50

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">

Sign up to request clarification or add additional context in comments.

4 Comments

Could you please to clarify what is document.getElementById('inp') is your code ? And how this related with my piece of code?
It is the <input> element which exposes the same kind of File object your code receives, but in far pess line of code for demonstrating that you can append these File objects to a FormData...
Pls look MODIFIED BLOCK
@PetroGromovo You are calling twice fileReader.readAsDataURL but your don't even need that FileReader. If you want to display the selected image, then just do this.previewImg.src = URL.createObjectURL( this.new_upload_ad_image ). Also editing questions in a way it invalidates current answers is seen as rude over here. I'm sure you didn't do it in bad faith, but beware I answered the first revision's question. I don't answer step-by-step debugging questions.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.