javascriptmarko

How does one access `$global` or `out.global` in non-top-level components in MarkoJS?


I'm trying to access global variables from a Marko component, but I'm getting Uncaught ReferenceError: out is not defined.

class {
    onClick(event) {
        console.log(out.global.message)
        event.preventDefault()
    }
}

Shouldn't out.global/$global be accessible everywhere?


Solution

  • out is made available to components in certain lifecycle methods -- onCreate(input, out), onInput(input, out), and onRender(out). In one of those, assign the value you'd like to this in order to make it accessible elsewhere in the class:

    class {
        onCreate(input, out) {
            this.message = out.global.message
        }
    
        onClick(event) {
            console.log(this.message)
            event.preventDefault()
        }
    }
    

    For non-top-level components, state and properties are not automatically serialized, so the above code would cause this.message to be set in the component on the server, but that property would be undefined on the client.

    To make out.global.message available on the client to non-top-level components, you have to change the render function to specify that it should be serialized, as in the docs on server-side rendering:

    template.render({
        $global: {
            serializedGlobals: {
                message: true
            }
        }
    }, res);