How to use rails active_storage to get upload progress in third-party js libraries

Direct transfer instructions for rails files

ides.rubyonrails.org/active_storage_overview.html-sharpdirect-uploads" rel=" nofollow noreferrer "> Direct Uploads tutorial

my usage

import { DirectUpload } from "activestorage"

uploadFile (file) {
        // activestorage: direct_upload
        let vm = this
        const url = "/rails/active_storage/direct_uploads"
        const upload = new DirectUpload(file, url, upload)

        return new Promise((resolve, reject) => {
          upload.create((error, blob) => {
            if (error) {
              console.log(error)
              vm.$Message.error(error)
            } else {
              // Add an appropriately-named hidden input to the form with a value of blob.signed_id
              console.log(blob)
              resolve(blob.signed_id)
            }
          })
        })
      }

demand

you want to add the upload progress prompt, so you need to get the upload progress

question

example of the tutorial is:

import { DirectUpload } from "activestorage"
 
class Uploader {
  constructor(file, url) {
    this.upload = new DirectUpload(this.file, this.url, this)
  }
 
  upload(file) {
    this.upload.create((error, blob) => {
      if (error) {
        // Handle the error
      } else {
        // Add an appropriately-named hidden input to the form
        // with a value of blob.signed_id
      }
    })
  }
 
  directUploadWillStoreFileWithXHR(request) {
    request.upload.addEventListener("progress",
      event => this.directUploadDidProgress(event))
  }
 
  directUploadDidProgress(event) {
    // Use event.loaded and event.total to update the progress bar
  }
}

Source code: https://github.com/rails/rail.

Shouldn"t the instance of

DirectUpload be able to access the directUploadWillStoreFileWithXHR, directUploadDidProgress method, but if I call it this way, I will report an error without this method. Ask for help

Aug.30,2021

I finally get that we need to write the Uploader class half by ourselves.

uploader.js

import { DirectUpload } from "activestorage"

export default class Uploader {
  constructor(file, url, vm) {
    this.file = file
    this.url = url
    this.vm = vm
    this.directUpload = new DirectUpload(this.file, this.url, this)
  }
 
  upload() {
    return new Promise((resolve, reject) => {
      this.directUpload.create((error, blob) => {
        if (error) {
          // Handle the error
          reject(error)
        } else {
          // Add an appropriately-named hidden input to the form
          // with a value of blob.signed_id
          resolve(blob)
        }
      })
    })
  }
 
  directUploadWillStoreFileWithXHR(xhr) {
    xhr.upload.addEventListener("progress",
      event => this.directUploadDidProgress(event))
  }
 
  directUploadDidProgress(event) {
    // Use event.loaded and event.total to update the progress bar
    let percent = ((event.loaded / event.total) * 100).toFixed(1)
    console.log(percent)
    // (iview)
    this.vm.$Loading.update(percent)
  }
}

use like:

import Uploader from 'path/to/uploader.js'

const uploader = new Uploader(this.file, '/rails/active_storage/direct_uploads', this)

uploader.upload().then(blob => {
    // to do your request
    ...
}, error => {
    // report the error
    vm.$Message.error(error)
    vm.$Loading.error()
})

I have another confuse, how can I get the progress data when I use Uploader class?

related issue:
https://github.com/rails/rail.

Menu