Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How can I access a suspenseQuery's state while in-flight? #73

Open
Esya opened this issue Feb 26, 2024 · 4 comments
Open

How can I access a suspenseQuery's state while in-flight? #73

Esya opened this issue Feb 26, 2024 · 4 comments

Comments

@Esya
Copy link

Esya commented Feb 26, 2024

I have the following, typical, suspenseQuery atom :

export const productsQueryAtom = atomWithSuspenseQuery((get) => {
    const params = get(fetchProductsParamsAtom)
    const trpc = get(trpcAtom)
    return {
        queryKey: ['inventoryProducts', params],
        queryFn: () => {
            return trpc.inventory.getInventoryProducts.query(params)
        },
    }
})

I would like to derive a status atom/access the other properties of the query (or the query key without duplicating the logic) but if I try to make a derive read atom :

  • If it's async, then it only runs when the query has completed
  • If it's not async (example below) then I get the promise but I can't get the query key
export const productsStatusAtom = atom((get) => {
    // Query is a promise here, how do I access it's queryKey or it's `fetchStatus` ?
    const query = get(productsQueryAtom)
    
    // The goal is to get to the react-query query state
    return status
})

I essentially want to build something similar to pmndrs/jotai#2228 to have stale-while-revalidate content but also want to get the properties of the query instead of just basing myself on the status of the promise. Any idea? Thanks!

@kalijonn
Copy link
Collaborator

Suspense Query doesn't have fetching status. Its created in a way to always have data as defined and hence the status is always 'success'. If you want to use previous state, you would typically want to use startTransition

With the unwrap util, you can understand when the promise is pending. query in your example would be undefined when the promise is pending. This is helpful if you only want to know if a promise is pending or not.

@Esya
Copy link
Author

Esya commented Feb 27, 2024

I think you're referring to status but I am referring to fetchStatus which is also set on suspense queries and gives you the ability to know when a query is being fetched or idle.

I want a loader to be displayed alongside the data when the query is fetching, even after the query has already resolved initially.

I suppose I could build something with unwrap where if the query is pending I can assume it to be fetching and if it's not I can access the fetchStatus property but that does not seem very elegant

@kalijonn
Copy link
Collaborator

if the query is pending I can assume it to be fetching and if it's not I can access the fetchStatus property

Seems right. Sorry about the misunderstanding earlier.

that does not seem very elegant

Do you have an api in mind? Maybe we can come up with an abstraction to improve DX?

@grzesiekgs
Copy link

grzesiekgs commented Feb 27, 2024

@Esya I'm not 100% sure that it is what You need:

export const productsStatusAtom = atom((get) => {
  const queryResultStatus = get(loadable(productsQueryAtom))
  // Most likely you also want to handle error state
  if (queryResultStatus.state === 'hasData') {
    return queryResultStatus.fetchStatus
  }
  
  return 'fetching'

})

As far as I see queryResult.fetchStatus is getting updated each time when query is refetching data.

@kalijonn If You are open to adding some abstraction-atoms, then I have few in mind already, some related to this case, and some related to changes introduced in version 0.8.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants