I'm trying to render a component when the onMount
is triggered in my smart component. The server seems to render the component correctly but when onMount
is triggered on the client it does not render, I get a simple undefined
.
const button = require('src/client/components/a-button');
console.log(button); // --> { path: '/home/karl/dev/instanty/node/src/client/components/a-button.marko.js', _: [Getter/Setter], '$__shouldBuffer': true, meta: {} }
const htmlServer = button.renderToString({ label: 'Click me!' }); // <-- works
console.log(htmlServer);
module.exports = class {
onMount() {
console.log(button); // --> Template {path: undefined, meta: undefined, _: function}
const html = button.renderToString({ label: 'Click me!' }); // <-- does not work
console.log(html);
}
//... more code
}
I'm requiring the component as stated here: http://markojs.com/docs/rendering/#rendering
I'm also using lasso, I suspect this might be why it's not working. I suspect that lasso isn't bundling the component and sending it to the client.
I read the following also: http://markojs.com/docs/lasso/#client-side-rendering
That's due to a limitation in Marko v4. Marko v4 was designed to render [V]DOM nodes and not HTML strings in the browser. If you really need the HTML string you will need to get the HTML string from the DOM node by using code similar to the following:
const html = button.renderSync({ label: 'Click me!' })
.getNode().firstChild.outerHTML;
NOTE: getNode()
returns a DocumentFragment
node because a UI component might render multiple top-level HTML elements. We use firstChild
in the code above to get the first node out of the DocumentFragment
and assume that is the HTML element node you are interested in.
With that said, we should update the docs to make this clear (or implement toString()
even though it really should not be needed).