Skip to content
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

syscall/js: any way of accessing javascript list members? #29212

Closed
sodadi opened this issue Dec 13, 2018 · 3 comments
Closed

syscall/js: any way of accessing javascript list members? #29212

sodadi opened this issue Dec 13, 2018 · 3 comments

Comments

@sodadi
Copy link

sodadi commented Dec 13, 2018

What version of Go are you using (go version)?

go1.11.1 windows/amd64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

go env Output
set GOARCH=wasm
set GOBIN=
set GOCACHE=C:\Users\asodhi\AppData\Local\go-build
set GOEXE=
set GOFLAGS=
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOOS=js
set GOPATH=C:\Users\asodhi\go;C:\Git\newStitchGeneration\go;
set GOPROXY=
set GORACE=
set GOROOT=C:\Go
set GOTMPDIR=
set GOTOOLDIR=C:\Go\pkg\tool\windows_amd64
set GCCGO=gccgo
set CC=gcc
set CXX=g++
set CGO_ENABLED=0
set GOMOD=
set CGO_CFLAGS=-g -O2
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-g -O2
set CGO_FFLAGS=-g -O2
set CGO_LDFLAGS=-g -O2
set PKG_CONFIG=pkg-config
set GOGCCFLAGS=-fPIC -fmessage-length=0 -fdebug-prefix-map=C:\Users\asodhi\AppData\Local\Temp\go-build750770322=/tmp/go-build -gno-record-gcc-switches

What did you do?

For our use case, I am creating a wasm file from the golang project, the callback function is passed a list of integers.

JS code: test(immutable_1.List([1, 2, 3]));

GOLANG code:
func test(params []js.Value){
param0:= params[0]
len1 := param0.Length()
fmt.Println("param0: ", param0)
fmt.Println("len: ", len1)
}

the println prints:
param0: List [ 1, 2, 3 ]
len: 0

Is there a way to access the list length and value at the indexes?

What did you expect to see?

I expected the list to behave like an array, the Length, and Index functions to work on it too

What did you see instead?

The array function not able to work on List

@bradfitz bradfitz changed the title Any way of accessing javascript list members through syscall/js syscall/js: any way of accessing javascript list members? Dec 13, 2018
@agnivade
Copy link
Contributor

Works for me.

index.html

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>Go wasm</title>
</head>
<body>
	<button id="close">Shutdown app</button>

	<script src="wasm_loader.js"></script>
	<script>
		const go = new Go();
		let mod, inst;
		console.log("Initializing wasm...");
		WebAssembly.instantiateStreaming(
			fetch("main.wasm", {cache: 'no-cache'}), go.importObject).then((result) => {
			mod = result.module;
			inst = result.instance;
			console.log("Initialization complete.");
			run();
			test([1, 2, 3]);
		});

		async function run() {
			await go.run(inst);
		}
	</script>
</body>
</html>

main.go

// +build js,wasm

package main

import (
	"fmt"
	"syscall/js"
)

var console = js.Global().Get("console")

func main() {
	// Setup callbacks
	cb := js.NewCallback(func(i []js.Value) {
		fmt.Println(i[0])
		fmt.Println(i[0].Length())
		fmt.Println(i[0].Type())
		arr := i[0]
		fmt.Println(arr.Index(0))
	})
	js.Global().Set("test", cb)
	done := make(chan struct{})

	shutdownCb := js.NewEventCallback(js.PreventDefault, func(ev js.Value) {
		done <- struct{}{}
	})
	js.Global().Get("document").
		Call("getElementById", "close").
		Call("addEventListener", "click", shutdownCb)

	<-done
	console.Call("log", "Shutting down app")
	cb.Release()
	shutdownCb.Release()
}

Output -

Initializing wasm... 
Initialization complete. 
1,2,3
3
object
1 

Attached the wasm_loader.js too.
Tested on FF63 and Chrome 69 in a Linux box.

wasm_loader.js.zip

I will close the issue now as I think the question has been adequately answered. We mainly track bugs here in the issue tracker. If you still face issues, I would request you to take a look at the Questions wiki page; it has a list of good places for asking questions.

@sodadi
Copy link
Author

sodadi commented Dec 15, 2018

hi @agnivade
This works with an array, the issue I am facing is with passing a list.

you explicitly called test([1, 2, 3]); :- here [1,2,3] will be array, the code works with an array

, try with a List.
To create a list, I am using the immutable package.

And creating the list like: immutable.List([1, 2, 3])

@agnivade
Copy link
Contributor

I see. Yes, it will not work in that case because that list is not a browser native type, rather an object with its own set of methods. Effectively, to the browser, that is just a normal object and it has no idea that it is internally a list. Since that object does not behave like an array, so you will not get that behavior in Go.

>>ff = Immutable.List([1,2,3])
Object { size: 3, _origin: 0, _capacity: 3, _level: 5, _root: null, _tail: {…}, __ownerID: undefined, __hash: undefined, __altered: false }
>>ff.length
undefined
>>ff[0]
undefined

So, essentially you are getting the stringified representation of it which is "List [ 1, 2, 3 ]". An alternative which you can consider is passing the array version of that list to Go, after you are done with the list operations - list.toArray()

@golang golang locked and limited conversation to collaborators Dec 15, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants