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

Skip to content

Enable a way to pass/access a JSON object from backend to frontend more efficiently (skipping unmarshaling from a string). #359

Open
@dmitshur

Description

@dmitshur

This is a very low priority enhancement that can be done. I've discussed it with @neelance in person and he said he wanted to support it in the long term. I'm reporting this here so it can be tracked, since I'll be deleting the relevant code from my WIP branch.

Right now, one way to pass some state from backend Go to frontend Go when using html/template package is the following pattern.

First, define a struct containing state you want to pass in a package that can be impoted by both backend and frontend Go code:

package page

// State that is passed to the frontend script from the backend handler.
type State struct {
    Foo int
    Bar bool
    Baz bazSpec
}

type bazSpec struct {
    Alpha string
    Beta  string
}

Then, in your html/template you have a little section:

<script type="text/javascript">
    var StateJSON = "{{.State | json}}"; // A string containing JSON-encoded state object.
</script>

State gets encoded into a JSON string.

Then, the frontend Go code will use json.Unmarshal to convert it from a string into page.State.

stateJSON := js.Global.Get("StateJSON").String()
var state page.State
err := json.Unmarshal([]byte(stateJSON), &state)
if err != nil {
    panic(err)
}

That works just fine. But there's a small opportunity to be more direct.

Since the frontend Go code gets compiled to JavaScript, in theory, it's possible to pass State as a real JavaScript object and then access it directly via GopherJS. E.g., something like:

// State that is passed to the frontend script from the backend handler.
type State struct {
    *js.Object
    Foo int
    Bar bool
    Baz bazSpec
}
<script type="text/javascript">
    var State = {{.State | json}}; // The actual JavaScript state object (not a string).
</script>

And on frontend:

var state page.State
state.Object = js.Global.Get("State")

// Now you can use state normally; and we skipped having to json.Unmarshal from a string.
_ = state.Foo

However, that currently isn't quite possible to do cleanly in the general case. There are some workarounds, but they require you to duplicate page.State struct, etc.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions