rich-text icon indicating copy to clipboard operation
rich-text copied to clipboard

Handle async data in custom renderer?

Open levimichael opened this issue 7 years ago • 7 comments

I'd like to use a custom renderer with documentToHtmlString() to retrieve an inline entry hyperlink's path in my application. I can't seem to get it to work though since the documentToHtmlString function is not waiting on the async data.

Thanks for any help!

levimichael avatar Mar 26 '19 20:03 levimichael

Confused by what you mean by this. If what you mean is that you have to fire off another request based on a retrieved ID, I would recommend doing that in a .then() on your first fetch prior to passing it into documentToHtmlString() and handling the patched data in the same place you are now. Does this help? Are you able to provide any code of what you are trying to do? The community slack channel is also helpful for this kind of stuff.

mgmolisani avatar Mar 28 '19 01:03 mgmolisani

Hey @levimichael, at the moment, rich-text-html-renderer doesn't support async operations in renderers. As @mgmolisani said, we recommend fetching the data before rendering.

Providing more details and context will help us fully understand the issue and find a way to work around it.

sbezludny avatar Mar 28 '19 06:03 sbezludny

Hi! I think I have the same issue. As the document with embedded assets only returns the object with the id, I created a helper to resolve the dependency and get all the info for that object. With the following code, I get something like [object Promise]<p><b>Some</b> <i>description</i></p>

  const document = {
    nodeType: 'document',
    content: data
  }

  const options = {
    renderNode: {
      [BLOCKS.EMBEDDED_ASSET]: async (node) => {
        const asset = await resolveDependencies(node)
        return `<img src="${asset.Item.url}">`
      }
    }
  }

  const doc = documentToHtmlString(document, options)

It would be great to send the function and that documentToHtmlString wait for the response to return the resolved object

danielavpr avatar Apr 10 '19 21:04 danielavpr

You have to handle the asynchronous call before passing anything to documentToHtmlString. So get your initial document tree as JSON, then parse that tree for assets, fetch those assets by ID, and patch them into the original tree. Then that new tree is your document argument. Making the lazy evaluated renderer async does not make the calling function wait on it. It just means it itself will not resolve immediately. That’s why it is returning an unresolved promise and printing its toString value.

mgmolisani avatar Apr 10 '19 21:04 mgmolisani

It would be more interesting to see a recursively asynchronous rich text fetch package. The renderer should really be free of side effects and such a package would allow all other packages to benefit without requiring update.

Edit: The way I suggested in this post to fork the repo and edit was incomplete so I removed it to avoid confusion. It would not work as I suggested without other edits to the renderer. I stand by the idea of a separate package to handle building the tree then synchronously reading that new tree.

mgmolisani avatar Apr 10 '19 22:04 mgmolisani

I already made it in that way (handle the asynchronous call and pass the new tree to documentToHtmlString and it works well. Thank you for your help!

danielavpr avatar Apr 11 '19 16:04 danielavpr

I already made it in that way (handle the asynchronous call and pass the new tree to documentToHtmlString and it works well. Thank you for your help!

Do you mind sharing your solution?

snovos avatar Oct 07 '20 20:10 snovos