Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Arrays in JS objects don't seem to work as I'd expect #460

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
theclapp opened this issue May 13, 2016 · 3 comments
Closed

Arrays in JS objects don't seem to work as I'd expect #460

theclapp opened this issue May 13, 2016 · 3 comments

Comments

@theclapp
Copy link

o := struct {
    *js.Object
    a []int `js:"a"`
    b js.M  `js:"b"`
}{Object: js.Global.Get("Object").New()}
o.a = []int{1}
o.b = js.M{"x": "x"}
fmt.Printf("%v ", o.a[0])
o.a[0] = 2 // <== this doesn't work
fmt.Printf("%v ", o.a[0])

o.Get("a").SetIndex(0, 3) // <== this works but is awkward
fmt.Printf("%v\n", o.a[0])

fmt.Printf("%v ", o.b["x"])
o.b["x"] = "y" // <== this doesn't work either
fmt.Printf("%v ", o.b["x"])

o.Get("b").Set("x", "z") // <== works but awkward
fmt.Printf("%v ", o.b["x"])

result:
1 1 3
x x z

Expected:
1 2 3
x y z

Playground

As near as I can tell, the array "a" gets $internalize()'ed into a whole new array, which is assigned to and then thrown away. Similarly, "b" gets $internalized()'ed into a whole new object, which is assigned to and then thrown away.

Should one just not put slices or maps in JS objects?

@theclapp theclapp changed the title Arrays in JS objects don't seem to work correctly Arrays in JS objects don't seem to work as I'd expect May 13, 2016
@thanhps42
Copy link

Me too, slices ad maps in gopherjs make me confused

@theclapp
Copy link
Author

Putting "non-scalar" types (like slices, arrays, and maps) in JS-structs doesn't work, for the reason given in my initial comment (an internalized array is assigned to and then thrown away). This is the best I've been able to come up with:

o := struct {
	*js.Object
	a *js.Object `js:"a"` // used as an array
	b *js.Object `js:"b"` // used as a map
}{Object: js.Global.Get("Object").New()}

println("At initialization time:")
o.a = js.Global.Get("Array").New(0, 1, 2)
o.b = js.Global.Get("Object").New(js.M{"x": "y"})
println(o.a) // => [ 0, 1, 2 ]
println(o.b) // => { x: 'y' }

println("\nAfter being modified:")
o.a.SetIndex(2, 3)
o.b.Set("x", "z")
println(o.a) // => [ 0, 1, 3 ]
println(o.b) // => { x: 'z' }

transpiles to

// Printing elided ...
o = new structType.ptr(new ($global.Object)(), null, null);
o.Object.a = new ($global.Array)(0, 1, 2);
o.Object.b = new ($global.Object)($externalize($makeMap($String.keyFor, [{ k: "x", v: new $String("y") }]), js.M));
o.Object.a[2] = 3;
o.Object.b.x = $externalize("z", $String);

On the plus side, this bit of ickyness o.a.SetIndex(2, 3) maps to just this o.Object.a[2] = 3, so at least on the JS side it's fairly clean.

@theclapp
Copy link
Author

Added a link to this issue to the Tips and Gotchas wiki page.

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

No branches or pull requests

2 participants