Skip to content

How to build on Windows; how to get contents of a file from <input type="file"> as a []byte? #776

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
inkeliz opened this issue Mar 16, 2018 · 8 comments
Labels

Comments

@inkeliz
Copy link
Contributor

inkeliz commented Mar 16, 2018

src/syscall/syscall_nonlinux.go:5:18: undeclared name: SYS_EXIT
/src/syscall/syscall.go:53:39: too few arguments in call to Syscall

I'm using Windows and go1.10. I'm trying to build (gopherjs build) this code:

package main
//go:generate gopherjs build main.go -o js/app.js -m
// +build ignore

import (
  "log"
)

func main() {
    log.Println("Hello World")
}
@inkeliz inkeliz closed this as completed Mar 16, 2018
@inkeliz inkeliz reopened this Mar 16, 2018
@dmitshur
Copy link
Member

I don’t think any of GopherJS developers use or support Windows, so building with GOOS=windows likely doesn’t work. However, you should be able to build with GOOS=linux gopherjs build or GOOS=darwin gopherjs build.

@inkeliz
Copy link
Contributor Author

inkeliz commented Mar 16, 2018

Thank you so much, it works pretty nice. Even features that is not mentioned in the page of compatibilities.

I have one question, I think it's the last one, I don't know if I need to open one new issue. But, It's possible to get data from one <input type="file">? I mean the user "upload" the file, but instead of send it to one server the file is processed locally, using the JS which is compiled from Golang.

@dmitshur
Copy link
Member

dmitshur commented Mar 16, 2018

Yes, that is absolutely possible.

The <input> element has a files property that you can access. The type is FileList, which contains a list of File objects. You can convert a File to a byte slice and then run any Go code on it.

See https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement and https://developer.mozilla.org/en-US/docs/Web/API/FileList.

In the dom wrapper package, the files property is available via the HTMLInputElement.Files method.

@inkeliz
Copy link
Contributor Author

inkeliz commented Mar 16, 2018

I'll take a look in the first alternative, that uses the Javascript. I'm trying with HTMLInputElement.Files but don't have sucess for now, it only show [object File], one of my test was:

js.Global.Get("document").Call("write", `<input class="x" type="file">`)

root := dom.GetWindow().Document()
input := root.QuerySelector(".x")

input.AddEventListener("change", true, func(dom.Event) {
	f := input.(*dom.HTMLInputElement)
	fmt.Println(f.Files()[0].Object.String())
})

In the docs it says "The dom package does not define any methods on File nor does it provide access to the blob or a way to read it.". :\

@inkeliz
Copy link
Contributor Author

inkeliz commented Mar 16, 2018

I found one similar issue, dominikh/go-js-dom#32. I don't know if have a better method, if something change in the GopherJS since this issue. But for now I'm using something based in your code, in the reply. 👍

func blobToBytes(blob *js.Object) []byte {
	var b = make(chan []byte)
	fileReader := js.Global.Get("FileReader").New()
	fileReader.Set("onload", func() {
		b <- js.Global.Get("Uint8Array").New(fileReader.Get("result")).Interface().([]byte)
	})
	fileReader.Call("readAsArrayBuffer", blob)
	return <-b
}

func main() {

	js.Global.Get("document").Call("write", `<input class="x" type="file">`)

	root := dom.GetWindow().Document()
	input := root.QuerySelector(".x")

	input.AddEventListener("change", true, func(dom.Event) {
		go func() {
			result := blobToBytes(input.(*dom.HTMLInputElement).Files()[0].Object)
			fmt.Println(string(result))
		}()
	})
}

If someone have the same problem, but will be nice if the Files have something like .Bytes().

@inkeliz inkeliz closed this as completed Mar 16, 2018
@dmitshur
Copy link
Member

dmitshur commented Mar 16, 2018

In the docs it says "The dom package does not define any methods on File nor does it provide access to the blob or a way to read it.". :\

Indeed. You need to do it yourself with something like:

// blobToBytes converts a Blob to []byte.
func blobToBytes(blob *js.Object) []byte {
	b := make(chan []byte)
	fileReader := js.Global.Get("FileReader").New()
	fileReader.Set("onload", func() {
		b <- js.Global.Get("Uint8Array").New(fileReader.Get("result")).Interface().([]byte)
	})
	fileReader.Call("readAsArrayBuffer", blob)
	return <-b
}

Edit: You beat me to it. 👍

@dmitshur dmitshur changed the title syscall error How to build on Windows; how to get contents of a file from <input type="file"> as a []byte? Mar 16, 2018
dmitshur added a commit that referenced this issue Mar 16, 2018
Add instructions for what people should do when building with GopherJS
on unsupported platforms. Code generation works completely fine, but
syscalls (e.g., for gopherjs run) will only work on supported platforms.

Previously, this information was only in issues, people's heads, commit
messages, etc. It should be documented in README to provide clarity.

Rename "OS X" to "macOS", the current name of that operating system.
Rearrange sections to place more relevant information first. Mention
Linux before macOS consistently. Linux is placed first because it's open
source and more freely available than the proprietary macOS, so it's
easier to recommend it as an alternative.

Resolves #770.
Updates #776.
Updates #688.
dmitshur added a commit that referenced this issue Mar 17, 2018
Add instructions for what people should do when building with GopherJS
on unsupported platforms. Code generation works completely fine, but
syscalls (e.g., for gopherjs run) will only work on supported platforms.

Previously, this information was only in issues, people's heads, commit
messages, etc. It should be documented in README to provide clarity.

Rename "OS X" to "macOS", the current name of that operating system.
Rearrange sections to place more relevant information first. Mention
Linux before macOS consistently. Linux is placed first because it's open
source and more freely available than the proprietary macOS, so it's
easier to recommend it as an alternative.

Resolves #770.
Updates #776.
Updates #688.
@Azareal
Copy link

Azareal commented May 13, 2018

'GOOS' is not recognized as an internal or external command,
operable program or batch file.

That doesn't seem to work on Windows, but then again, I'm manually inputting it into the commandline + batch file.

@paralin
Copy link
Contributor

paralin commented Dec 11, 2018

@Azareal $env:GOOS="linux"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants