jotai: jotai/urql client getter get a wrong atom value

Hi, I am trying to use jotai to manage the state of an app with a login system. When a user login, app will receive a token and the app will use it to create an urql client with the token as the bearer key.

However, the app will crash whenever the login state change like this: login -> logout -> login (crash!), and saying Cannot read property 'query' of null . It looks like the getter in atomWithQuery somehow fetched an old value, but when I try to log the client they get, it all look fine (showing a client object). I wonder if I missed something, or it is a bug.

A small demo to the problem, the app will crash when you attempt to login the second time: Link
Stack-trace

TypeError
Cannot read property 'query' of null
Object.eval [as read]
https://codesandbox.io/static/js/sandbox.68fd4509e.js:1:100695
readAtomState
https://3mi3y.csb.app/node_modules/jotai/esm/index.js:258:33
eval
https://3mi3y.csb.app/node_modules/jotai/esm/index.js:261:25
Object.eval [as read]
https://codesandbox.io/static/js/sandbox.68fd4509e.js:1:100695
readAtomState
https://3mi3y.csb.app/node_modules/jotai/esm/index.js:258:33
eval
https://3mi3y.csb.app/node_modules/jotai/esm/index.js:241:13
readAtomState
https://3mi3y.csb.app/node_modules/jotai/esm/index.js:237:19
readAtom
https://3mi3y.csb.app/node_modules/jotai/esm/index.js:319:21
eval
https://3mi3y.csb.app/node_modules/jotai/esm/index.js:643:23
checkForUpdates
https://3mi3y.csb.app/node_modules/jotai/esm/index.js:69:30
eval
https://3mi3y.csb.app/node_modules/jotai/esm/index.js:521:63
eval
https://3mi3y.csb.app/node_modules/jotai/esm/index.js:521:43
flushPending
https://3mi3y.csb.app/node_modules/jotai/esm/index.js:511:11
eval
https://3mi3y.csb.app/node_modules/jotai/esm/index.js:406:5
Object.config.write
https://3mi3y.csb.app/node_modules/jotai/esm/index.js:632:7
writeAtomState
https://3mi3y.csb.app/node_modules/jotai/esm/index.js:384:30
writeAtom
https://3mi3y.csb.app/node_modules/jotai/esm/index.js:417:3
updateAtom
https://3mi3y.csb.app/node_modules/jotai/esm/index.js:562:40
eval
https://codesandbox.io/static/js/sandbox.68fd4509e.js:1:100695
eval
/src/App.js:59:4
  56 | const [token, setToken] = useState(null);
  57 | 
  58 | useEffect(() => {
> 59 |   setClient(generateClient(token));
     |  ^
  60 | }, [token]);
  61 | 
  62 | return (
View compiled
▶ 12 stack frames were collapsed.

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 28 (25 by maintainers)

Most upvoted comments

Makes sense. Thanks for your help. Let’s see if someone has some interests in this. cc @Thisen

I’ll look into it.

I added a few tests for the usecase that is supported by types right now. The tests are passing. I thought it’s an important step (to not break the already working functionality if we want to catch the timing issue), it’s also good to have tests for this as this is a common use case (re-initializing client based on authentication for example, like in my use case): https://github.com/pmndrs/jotai/pull/634

Hey folks! Sorry for the late response 😅 The issue is solved with the magical solution (that wasn’t intended to solve this issue) by @Pinpickle in jotai#v1.3.4.

Cannot read property of 'query' of null for client is present as it was before v1.3.4, however, this time, when it occurs, L195 is going to handle (delete) it & retries again, in the next try, client is going to be defined, so no error in that try!

I’m not confident if that’s the right approach. I doubt it. Let me merge #634 first.

For what it is worth, the urql official provider wouldn’t accept a null value for client, so it definitely seems like an edge case to be avoided and/or taken care of via guards that prevent even the use of such an atom if no client would exist.

Definitely seems like a documentation issue IMHO