2

I am currently using Go WASM to upload a file to a server. During the upload it shall emit a call to update the upload progress in the UI.

I am currently using the following struct to have an indication of the progress:

type progressReporter struct {
    r                 io.Reader
    fileSizeEncrypted int64
    sent              int64
    file              js.Value
}

func (pr *progressReporter) Read(p []byte) (int, error) {
    n, err := pr.r.Read(p)
    pr.sent = pr.sent + int64(n)
    pr.report()
    return n, err
}

func (pr *progressReporter) report() {
    go js.Global().Get("dropzoneObject").Call("emit", "uploadprogress", pr.file, pr.sent*100/pr.fileSizeEncrypted, pr.sent)
}

The upload happens in a promise:

func UploadChunk(this js.Value, args []js.Value) interface{} {
        [...]
    handler := js.FuncOf(func(this js.Value, args []js.Value) interface{} {
        resolve := args[0]
        reject := args[1]

        go func() {
            [...]

            body := new(bytes.Buffer)
            writer := multipart.NewWriter(body)
            part, err := writer.CreateFormFile("file", "encrypted.file")
            if err != nil {
                return err
            }
            _, err = part.Write(*data)
            if err != nil {
                return err
            }
            err = writer.Close()
            if err != nil {
                return err
            }
            pReporter := progressReporter{
                    r:                 body,
                    fileSizeEncrypted: fileSize,
                    sent:              offset,
                    file:              jsFile,
                }
            r, err := http.NewRequest("POST", "./uploadChunk", &pReporter)
            if err != nil {
                return err
            }
            r.Header.Set("Content-Type", writer.FormDataContentType())
            client := &http.Client{}
            resp, err := client.Do(r)

            if err != nil {
                return err
            }
            [...]
        }
}

Although the code works fine, all emit calls to update the UI are sent after the POST request is finished. Is there any way to have this call asynchronously?

The full source code can be found here

Force
  • 6,312
  • 7
  • 54
  • 85

0 Answers0