WebReflection / uhtml

A micro HTML/SVG render

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Question: how to render async inside template

sladiri opened this issue · comments

I see that only hyperHTML can render a promise inside a template.

How would I render a template which has another template but as a Promise?

this project renders any asynchronous chunk of the page through promises:
https://github.com/WebReflection/hn

the live version is here:
https://webreflection.github.io/hn/top/?1

TL;DR ... whenever you resolve a promise, re-render again, it's gonna be fine 👍

more details here: https://medium.com/@WebReflection/an-isomorphic-hacker-news-pwa-a26c3b9adf2c

TL;DR you don't need promises within holes, as the performance of re-rendering these are just fine

Thank you for you response. The standards approach looks very nice.

Just to explain, I am just re-rendering in a small new project I am working on. The re-rendeing uses async generators, similar to what is described here: https://crank.js.org/blog/introducing-crank

Not sure if you would get email updates on edits of my comments, sorry if my multiple replies are not needed.
I am basically doing the same thing with what you do with the fx function but async. And my question was about how to have multiple of such "update-queues" in a page. Your example only has one. But I found it is not hard to do, if a parent awaits a promise of its children last output (Promise, because the "getter" goes through the same queue as a new URL) before rendering. Again, only one parent at the top of the async tree calls updatePage, as you do.

const component = createComponent();

(async () => {
  for await (const update of component.stateStream) {
    if (update.state) {
      const html = await component.render(update.state);
      render(document.body, html);
    }
  }
})().catch((error) => console.error(error));
export const createComponent = (): Component<State> => {
  const service = new Service();
  const subComponent2 = createSubComponent2();
  const rerender = () => service.update();

  const render = async (state: State) => {
    const update2 = await subComponent2.state;
    return html`
      <section>
        <button onclick=${rerender}>rerender</button>
        <p>count ${state.count}</p>
      </section>

      <section>
        ${update2.state && subComponent2.render(update2.state)}
      </section>
    `;
  };

  return {
    render,
    get state() {
      return service.state;
    },
    get stateStream() {
      return service.stateStream;
    },
  };