Description
Consider the following test:
type StructWithNonIdentifierJsTags struct {
object *js.Object
Name string `js:"my name"`
}
func TestStructWithNonIdentifierJsTags(t *testing.T) {
s := StructWithNonIdentifierJsTags{
object: js.Global.Get("Object").New(),
}
const want = "Paul"
// externalise a value
s.Name = want
// internalise again
got := s.Name
if want != got {
t.Errorf("Value via non-identifier js tag field gave %q, want %q", got, want)
}
}
This currently fails at runtime (gopherjs test
) with:
/home/myitcv/.mountpoints/myitcv_io_react/src/myitcv.io/react/_vendor/src/github.com/gopherjs/gopherjs/test.554077738:28596
s.object.my name = $externalize("Paul", $String);
^^^^
SyntaxError: Unexpected identifier
at new Script (vm.js:51:7)
at createScript (vm.js:138:10)
at Object.runInThisContext (vm.js:199:10)
at Module._compile (module.js:624:28)
at Object.Module._extensions..js (module.js:671:10)
at Module.load (module.js:573:32)
at tryModuleLoad (module.js:513:12)
at Function.Module._load (module.js:505:3)
at Function.Module.runMain (module.js:701:10)
at startup (bootstrap_node.js:193:16)
FAIL github.com/gopherjs/gopherjs/js 0.185s
This is because the compiler currently translates field access (getting or setting) via the dot notation:
s.object.my name
Where a string contains a non-identifier value (e.g. space above) this is destined to fail.
Some external libraries (e.g. React) require properties to be set that are composed of non-identifier strings, e.g. https://reactjs.org/docs/dom-elements.html, where "data-*"
and "aria-*"
are used for attribute names.
An equivalent way to set properties is via the bracket notation:
s.object.["my name"]
Hence it probably makes more sense in general to use this for js tag compilation.
For more details see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Property_Accessors
PR that addresses this will follow shortly.