Server async/await outside methods (ssr)

I just released a neat package that I’ve mentioned on these forums before: npdev:async-proxy. It creates a way to call Meteor methods using async/await, which is pretty neat.

One thing that is a little bit off though, is that if you use it in React, it works great client side, but Promises don’t seem to resolve in SSR like they do in meteor methods.

So my question is, how can I resolve this? In my project, I have a local fork of npdev:async-proxy which has a separate implementation of the API for the server, and that API does not use a promise at all. On the client side, I use checks for isServer to make sure to either call it with await or not, but this is hacky. I’m wonder if there is a way to use Meteor.wrapAsync instead, but that would seem to conflict with await. What I’d really like is simply a way to tell React.renderToString (or React.renderToNodeStream) to resolve Promises it encounters, but maybe that’s just crazy talk!

What do you think?

It looks like there may be some useful packages in react-land to try, like React Resolver, hmmm.

Actually you can use apollo for that (without using graphql) as described in https://blog.apollographql.com/how-server-side-rendering-works-with-react-apollo-20f31b0c7348 as long as you do your data fetching with a dedicated fetchData instance method which gets called in your constructor.

I have a custom data capture system in place using MiniMongo on the server, and Ground DB on the client, with some glue to fetch the data over methods (it’s way faster to start, but also to avoid the pub/sub overhead, and to get offline support). It works - I ended up passing the promises up to my SSR method, and returning promise (actually, using async/await, which returns a promise) to onPageLoad. It works pretty well!

Maybe I was not clear or I misunderstood, what I suggested does not require you to change any of your data flow set up. It is just that, if you place your data bootstrapping methods into a specifically named method in your react components, their promises will have been resolved - through apollo’s getDataFromTree method - before rendering your react dom tree.

I have offered this solution because you mentioned react resolver, which essentially does the same through an inversed method of keeping references to promises through a react context. Apollo’s getDataFromTree on the other hand, walks your tree to find the fetchData methods. In the end, both solutions accrue a queue (map of promises) to resolve during SSR. The thing I like about fetchData is that it is agnostic of the way you prepare your data or whatever, because it is just a reference to some async piece of code that needs to resolve before rendering.

Oh! Got it. That is indeed very similar to what I did, though probably better tested, and battle hardened. It’s also certainly less manual, though my solution is nicely wrapped. Thanks for the info - I’ll look into it.

1 Like