[solved] preFetch call depends on another preFetch results

  • I have a couple of preFetch calls I need to make. One is for general data that’s needed throughout the site. It’s data is needed no matter what route you visit, so I have it defined in App.vue to guarantee it’s always called.

    Another set of preFetch data is only needed for just a specific route, so I have it defined on that route’s component.

    The problem is, the route-specific prefetch requires data from the result of the App’s preFetch. Specifically, the result of the App preFetch populates the store with an ID needed by a service call in the route preFetch. However, it appears that, although preFetch’s run in a certain order, they don’t wait for one to complete before executing the next.

    Any opinions on a good pattern to handle this?

  • Admin

    Couple preFetch with your Vuex store. You got the store param there.

  • Can you explain in a bit more detail? If a preFetch needs to wait for an ID to be set on a vuex store (which is set by the App.vue’s preFetch), how does it monitor the store and wait for it to be set?

    If this were running client side, it would make more sense to me. I’d probably use a watcher or something.

  • So, I discovered the store.watch() api method. I could return a new Promise() from my prefetch, then setup a store.watch() to wait for certain vuex state to get set (by another preFetch) and then resolve that promise with another store.dispatch.

    The problem? store.watch() reactivity doesn’t appear to function in SSR mode. It works great when converting my preFetch() methods to mounted(), forcing them to run client side. However, in SSR, the store.watch simply won’t execute my callback when the state it’s watching changes.

    So I"m still stumped on how to pull this off.

  • Admin

    Return a Promise inside the preFetch in App.vue. It’s one of the reasons for using preFetch – it can wait for any asynchronous work. So put a Promise there that will allow Quasar to wait until it’s fulfilled then go on with your app execution.

    preFetch ({ store }) {
      return new Promise(...//inject store, do any async work you want....)

  • Sure, I just couldn’t figure out how that promise could be notified when another asynchronous preFetch, in a different component, was finished. It’s not like I can watch for state changes on the store since reactivity is turned off in SSR mode. It’s almost like I’d need to setup a timer to keep checking the state changes, which is usually my last resort.

    I decided to move that logic to a store action. So I ended up with just one preFetch which calls a store action, and that action ends up making the other service calls to get the data it needs before carrying out its intended action. It’s not my ideal design choice, but it gets the job done.

  • This appears to have been fixed with https://github.com/quasarframework/quasar-cli/issues/173. With that change, it appears that parent preFetches (such as those in App.vue) are fully resolved before child preFetches.

Log in to reply