how to upload and access a file
rtrzebinski opened this issue · comments
Hi, I'm looking for a way to upload a (CSV) file, and access its content, what I have now:
app.Input().ID("csv-upload-button").Type("file").Name("csv-import.csv").Accept(".csv").OnInput(c.handleCsvUpload),
func (c *Exercises) handleCsvUpload(ctx app.Context, e app.Event) {
app.Log("handleCsvUpload")
// now what? :D
}
When I click the button the file is set in the browser, but not uploaded automatically. I know I could add a submit button, but ideally I'd like to:
- auto upload the file once selected by the user
- access this file in my app
Thank you.
Here's an option:
func (r *Exercises) handleCsvUpload(ctx app.Context, e app.Event) {
// TODO:
// This does not handle multiple files.
// Validate file type which can be changed by the user in the file picker.
file := e.Get("target").Get("files").Index(0)
fmt.Println("name", file.Get("name").String())
fmt.Println("size", file.Get("size").Int())
fmt.Println("type", file.Get("type").String())
if data, err := readFile(file); err != nil {
fmt.Println(err)
} else {
fmt.Println(string(data))
}
}
func readFile(file app.Value) (data []byte, err error) {
done := make(chan bool)
// https://developer.mozilla.org/en-US/docs/Web/API/FileReader
reader := app.Window().Get("FileReader").New()
reader.Set("onloadend", app.FuncOf(func(this app.Value, args []app.Value) interface{} {
done <- true
return nil
}))
reader.Call("readAsArrayBuffer", file)
<-done
readerError := reader.Get("error")
if !readerError.IsNull() {
err = fmt.Errorf("file reader error : %s", readerError.Get("message").String())
} else {
uint8Array := app.Window().Get("Uint8Array").New(reader.Get("result"))
data = make([]byte, uint8Array.Length())
app.CopyBytesToGo(data, uint8Array)
}
return data, err
}
I wouldn't figure it out myself in a million years :D (not a frontend developer)
Works lika a charm, thank you so much Matt! @mlctrez
One more thing - I've made a change as suggested and it works fine -> rtrzebinski/simple-memorizer-4@96912ed
However it only works once, if I upload 2nd time, it does nothing.
When I refresh the page, it works again (again only once).
What should I do for it to work multiple times?
Perhaps the JS object needs to be reset somehow?
I tried:
c.Update()
but no effect 🤔
Added file input reset on last line of this method:
func (r *Exercises) handleCsvUpload(ctx app.Context, e app.Event) {
// TODO:
// This does not handle multiple files.
// Validate file type which can be changed by the user in the file picker.
file := e.Get("target").Get("files").Index(0)
fmt.Println("name", file.Get("name").String())
fmt.Println("size", file.Get("size").Int())
fmt.Println("type", file.Get("type").String())
if data, err := readFile(file); err != nil {
fmt.Println(err)
} else {
fmt.Println(string(data))
}
// reset file input for next upload
e.Get("target").Set("value", "")
}
Perfect, thank you @mlctrez it helped :)