sannajammeh / trpc-swr

tRPC-ified SWR hooks
https://trpc-swr.vercel.app
MIT License
209 stars 5 forks source link

Conditional fetching #55

Closed lukaswiklund closed 7 months ago

lukaswiklund commented 9 months ago

Hey, and thank you for this library.

I would love to be able to use conditional fetching just like the base SWR library. I'm currently using the isDisabled option which is an okay workaround, but to keep the integrity of the type checking that would be great!

sannajammeh commented 8 months ago

Unfortunately this is not possible as the key is generated by tRPC. Which type checking errors are you facing?

lukaswiklund commented 8 months ago

Unfortunately this is not possible as the key is generated by tRPC. Which type checking errors are you facing?

Okay I see, that's unfortunate. My use case is the following. I need to explicitly set a random value for TypeScript.

const order = swr.payment.order.getOrderById.useSWR(content.orderId ?? -1, {
    isDisabled: content.orderId === null,
})

I would love to be able to the same I would do in the base SWR library so that if content.orderId is null it will not fetch until it isn't.

const order = swr.payment.order.getOrderById.useSWR(content.orderId)

And thank you for your work with this library!

sannajammeh commented 8 months ago

I don't see where typescript would error in your case. isDisabled is performing conditional fetching using SWR's mechanism under the hood. The reason isDisabled was introduced is to handle this exact case.

The reason we won't be able to change this is that there is no longer a key argument. The key argument is the path payment.order.getOrderById combined with the query data content.orderId. tRPC allows for any kind of values added to the query, this includes null values.

lukaswiklund commented 8 months ago

No, there is no error in my above example. I however need to add a fallback value for the null value in the input to the tRPC function – a fallback that is never used as a value. This also requires the developer to remember both that and adding the isDisabled flag with the same variable. Not a big issue but not a very idiomatic TypeScript solution. I understand that it may not be possible and this alternate solution still solves the problem! 😀

sannajammeh commented 8 months ago

I see the issue now. As TS will attempt to enforce the input value to be what tRPC expects. The solution would be to move this logic inside its own component and only render it if the value is not null. That'd be the normal "React style" way to do this as well.

Otherwise, you can always opt out of tRPC-SWR for this specific use case like so:

Option 1 - manually fetch while keeping the same keys

const {client} = swr.useContext();
const getKey = () => content.orderId ? swr.payment.order.getOrderById.getKey(content.orderId) : null!;
const {data, ...} = useSWR(getKey(), () => {
  return client.payment.order.getOrderById(content.orderId!) // Same solution as Option 2
})

Option 2 - Use ! to tell typescript that key will be defined

Since we know isDisabled will pause the query until the key exists, you can just tell TS to ignore the issue.

const order = swr.payment.order.getOrderById.useSWR(content.orderId!, {
  isDisabled: content.orderId === null
})