lit-htmllit

Render lit / lit-html TemplateResult as string


In lit/lit-html/lit-element, a standard component is the TemplateResult (usually HTMLTemplateResult), created like:

function renderMe(msg) {
    return html`<div>Hello ${msg}!</div>`;
}

and of course the power and efficiency of the library is that subsequent calls will reuse the same <div> Element and only replace the changed fragments.

For testing the renderMe() function above, however, it would be helpful to be able to see the return value as a standard string, like:

assert.equal(
    RENDER_AS_STRING(renderMe('kimiko')), 
    '<div>Hello kimiko!</div>'
);

and fix any bugs in the function before testing how it renders into the browser itself.

Is there a function like RENDER_AS_STRING either in lit itself or in a testing library? I have searched and not found one.


Solution

  • The result of execution contains html strings and values that alternate:

    enter image description here

    We can combine them in the same order:

    function renderMe(msg) {
        return html`<div>Hello ${msg}!</div>`;
    }
    
    const getRenderString = (data) => {
      const {strings, values} = data;
      const v = [...values, ''] // + last emtpty part
      return strings.reduce((acc,s, i) => acc + s + v[i], '')
    }
    
    console.log(getRenderString(renderMe('SO')))
    

    You can test it in the playground

    And the recursive version

    import {html, css, LitElement} from 'lit';
    
    function renderMe(msg) {
        return html`<p>Hello ${msg}!</p>`;
    }
    
    function renderBlock(msg) {
        return html`<div>${renderMe(msg)}</div>`;
    }
    
    const getRenderString = (data) => {
      const {strings, values} = data;
      const v = [...values, ''].map(e => typeof e === 'object' ? getRenderString(e) : e )      
      return strings.reduce((acc,s, i) => acc + s + v[i], '')
    }
    
    document.getElementById('output').textContent = getRenderString(renderBlock('SO'))