Struct and js.Object Conversions

163 views
Skip to first unread message

Eric Anderton

unread,
May 20, 2015, 8:12:25 AM5/20/15
to goph...@googlegroups.com
I'm stumped: is there any canonical way to convert a struct's fields into a *js.Object?

I think I'm following the documentation correctly, that the currently supported conversions are exposing an interface via MakeWrapper, and implicitly converting *to* a struct via embedded js.Object w/ field tags.  But there doesn't appear to be a way to copy a struct's fields to js.Object.  That is, unless I'm misunderstanding how to use the library, which is entirely possible!

- EA

Richard Musiol

unread,
May 20, 2015, 8:50:57 AM5/20/15
to Eric Anderton, goph...@googlegroups.com
Hi Eric,

I'm having a hard time understanding your case. Could you give some example code that explains what you want to do?

Cheers,
Richard

--
You received this message because you are subscribed to the Google Groups "GopherJS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to gopherjs+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Eric Anderton

unread,
May 20, 2015, 1:49:28 PM5/20/15
to goph...@googlegroups.com, eric.t....@gmail.com
Sure thing, Richard.

The gist here is that I'd like to leverage the `js` tags to convert a struct TO js.Object, in order to hand off data to JavaScript code.  That and I would love to use an API function to do this job; the code below uses a javascript function "trampoline" instead.

The code below helps spell out the best I could figure out by reading the documentation and the codebase.  I can get the struct in a JavaScript function call, but it uses the exported struct field names instead:

http://www.gopherjs.org/playground/#/wjNXKc7L0O

package main

import (
    "fmt"
    "github.com/gopherjs/gopherjs/js"
)

type Foo struct {
    Value string `js:"xyz"`
}

func main() {
    converter := js.Global.Call("eval", `(
        function(x) { return x; }
    )`)
   
    foo := Foo { Value: "hello world" }
   
    fooObj := converter.Invoke(foo)
   
    fmt.Println("foo.xyz", fooObj.Get("xyz"))
    fmt.Println("foo.Value", fooObj.Get("Value"))
}

//////////////

foo.xyz undefined
foo.Value hello world

Dmitri Shuralyov

unread,
May 22, 2015, 1:01:29 AM5/22/15
to goph...@googlegroups.com
Hi Eric,

I may not have completely understand what you're looking to do, but I may have a guess. Let me share this snippet of code in case it is helpful to you.


That's the approach I've used to create a js.Object (for the JavaScript world) with the specified field names. I had to use a map instead of a struct, because `js:"xyz"` field tags are ignored by GopherJS, they are only used by encoding/json package inside the Go world.

(Sorry if this is not relevant to what you're actually asking... I'm unsure if I understood you correctly.)

Rusco

unread,
May 22, 2015, 4:53:56 AM5/22/15
to goph...@googlegroups.com
Hi Eric,
there are 2 cases:

A) You want to use your GopherJs Code in a JS Lib ? Then have a look at the "Pet" example on the front page. A calling sequence with a NodeJS console could look like this:

    nodejs>var p = pet.New("somepet")
    nodejs>p.SetName("GopherJS")
    undefined
    nodejs>p.Name()
    GopherJS


B) You want to use a JS Lib: have a look at the many bindings like the DOM or JQuery bindings.In this case a js-Tag is a renaming for acessing the properties.

This helps ?

Eric Anderton

unread,
May 22, 2015, 7:00:45 PM5/22/15
to goph...@googlegroups.com
(Sorry if this is not relevant to what you're actually asking... I'm unsure if I understood you correctly.)

No, that actually helps.  The map example is a good one.  In fact, I'm doing some things like this right now as a stopgap.  It's good to know that I converged on a solution that someone else cooked up.

The ideal solution would be a general purpose function that would scoop up fields based on a tag that builds this map dynamically.  That shouldn't be too tough... :)

Eric Anderton

unread,
May 22, 2015, 7:03:52 PM5/22/15
to goph...@googlegroups.com


On Friday, May 22, 2015 at 4:53:56 AM UTC-4, Rusco wrote:
Hi Eric,
there are 2 cases:

A) You want to use your GopherJs Code in a JS Lib ? Then have a look at the "Pet" example on the front page. A calling sequence with a NodeJS console could look like this:

    nodejs>var p = pet.New("somepet")
    nodejs>p.SetName("GopherJS")
    undefined
    nodejs>p.Name()
    GopherJS


B) You want to use a JS Lib: have a look at the many bindings like the DOM or JQuery bindings.In this case a js-Tag is a renaming for acessing the properties.

This helps ?

I greatly appreciate the help. :)  This side of GopherJS - MakeWrapper() - works well when you need to expose functions and have property accessors ready to go.  With something like PolymerJS, the only part that matters is the data (fields), as that's what gets rolled up into two-way binding.

My dilemma is that it appears that there's no analogue to MakeWrapper that spits out a *js.Object with just the exported struct fields on it.  That's something that would make my binding library trivial to write.

Ben Echols

unread,
May 26, 2015, 11:19:39 AM5/26/15
to goph...@googlegroups.com
If you return the object directly it will automatically be converted to a js object that has only the struct fields exposed (not functions).

// go
type AStruct struct {
  Value string
}
func MyFunc() AStruct {
  return A{Value: "asdf"}
}

// js

var a = MyFunc();
console.log(a.Value);

// output 
asdf
Reply all
Reply to author
Forward
0 new messages