Is RefetchQueries deprecated?

I used to use refetchQueries in my components but lately I’m getting a TS2345 on it:

TS2345: Argument of type ‘{ refetchQueries: { query: any; }; }’ is not assignable to parameter of type ‘GraphQLHookOptions’

So assuming I missed something I went into the repo and the doc to find more information.
In the repo we have this, which removes the original refetchQueries and explains that cache is handled in a different way through Apollo’s cache updating policy:

Yet in the doc we still have this:
https://redwoodjs.com/tutorial2/creating-a-comment-form.html#updating-the-form-refetch

Are we missing a doc update? Which is the recommended way to update the other cells?

Is this a TypeScript file?

Without looking in to it, I’d guess this is a limitation of our current typings regarding graphql. To confirm, could you just tell TS to ignore that line, and see if everything work when you actually run it?

Yes that’s a Typescript file indeed

I did this:

const [createPaymentMethod, { error, loading }] = useMutation(
    CREATE_PAYMENT_METHOD_MUTATION,
    {
      // eslint-disable-next-line @typescript-eslint/ban-ts-comment
      // @ts-ignore
      refetchQueries: [{ query: CardsCell.QUERY }],
    }
  )

I have this popping:

Uncaught Invariant Violation: query option is required. You must specify your GraphQL document in the query option.
    at new InvariantError (http://localhost:8910/static/js/app.chunk.js:110148:28)
    at invariant (http://localhost:8910/static/js/app.chunk.js:110160:15)
    at QueryManager.push../node_modules/@apollo/client/core/QueryManager.js.QueryManager.query (http://localhost:8910/static/js/app.chunk.js:71742:92)
    at http://localhost:8910/static/js/app.chunk.js:71584:84
    at Array.forEach (<anonymous>)
    at Object.complete (http://localhost:8910/static/js/app.chunk.js:71565:60)
    at notifySubscription (http://localhost:8910/static/js/app.chunk.js:67699:18)
    at onNotify (http://localhost:8910/static/js/app.chunk.js:67733:3)
    at SubscriptionObserver.complete (http://localhost:8910/static/js/app.chunk.js:67799:7)
    at http://localhost:8910/static/js/app.chunk.js:76209:68
    at Array.forEach (<anonymous>)
    at iterateObserversSafely (http://localhost:8910/static/js/app.chunk.js:76209:25)
    at Object.complete (http://localhost:8910/static/js/app.chunk.js:76030:101)
    at notifySubscription (http://localhost:8910/static/js/app.chunk.js:67699:18)
    at onNotify (http://localhost:8910/static/js/app.chunk.js:67733:3)
    at SubscriptionObserver.complete (http://localhost:8910/static/js/app.chunk.js:67799:7)
    at notifySubscription (http://localhost:8910/static/js/app.chunk.js:67699:18)
    at onNotify (http://localhost:8910/static/js/app.chunk.js:67733:3)
    at SubscriptionObserver.complete (http://localhost:8910/static/js/app.chunk.js:67799:7)
    at http://localhost:8910/static/js/app.chunk.js:72911:26

That’s my CardsCell.tsx :

import { createElement } from 'react'
import CreditCard from 'src/components/PaymentMethod/CreditCard'
import Presentation from 'src/components/PaymentMethod/Presentation'

export const QUERY = gql`
  query PAYMENT_METHODS {
    paymentMethods {
      id
      name
    }
  }
`

export const Empty = () => <CreditCard />

export const Success = ({ paymentMethods, component = Presentation }) => (
  <>
    {paymentMethods.length <= 5 && <CreditCard />}
    {paymentMethods?.length &&
      paymentMethods.map((paymentMethod) =>
        createElement(component, { ...paymentMethod })
      )}
  </>
)

I’m guessing CardsCell.QUERY is undefined. What does the import of CardsCell look like? What if you console.log it?

import CardsCell from 'src/components/PaymentMethod/CardsCell'

From my terminal:

$ l web/src/components/PaymentMethod/CardsCell.tsx 
-rwxrwxrwx 1 noire www-data 728 feb  7 10:44 web/src/components/PaymentMethod/CardsCell.tsx

I’m using the exact same import in a Page component where it works flawlessly.
I have tried the console.log inside the module, then within the module’s Component, on the Page component the CardsCell appears as loaded both inside the module and inside the Page component.
On the Presentation component - where I first saw the issue, the console.log is undefined in the module, but it prints properly from inside the component.

Still, if I try to console.log precisely the CardsCell.QUERY prop it appears as undefined.

Eventually I tried this:

import { QUERY as CardsCellQuery } from './CardsCell'

which happens to do the trick, even if I may get a warning about using Apollo’s merge functions for cache updates.

So… there’s definitely something weird around and I’ll have to modify the entire codebase.
Any idea what might have happened?

Try this

import CardsCell, { QUERY } from 'src/components/PaymentMethod/CardsCell'

// ...

const [createPaymentMethod, { error, loading }] = useMutation(
  CREATE_PAYMENT_METHOD_MUTATION,
  {
    // eslint-disable-next-line @typescript-eslint/ban-ts-comment
    // @ts-ignore
    refetchQueries: [{ query: QUERY }],
  }
)

Your Cell component has a bunch of named exports, one of them being QUERY. Then RW will come and add a default export for you at the end of the file. Something like

export default withCell({ QUERY, Loading, Succes, Failure, beforeQuery })

So to use the Cell component you do

import CardsCell from 'src/components/PaymentMethod/CardsCell'

To use the QUERY you do

import { QUERY } from 'src/components/PaymentMethod/CardsCell'

To use both you do

import CardsCell, { QUERY } from 'src/components/PaymentMethod/CardsCell'
1 Like

I’ll accept this as the solution, it used to work before with a different notation but this one is fine to me and using an alias is clean enough when we have multiple queries to fetch.

Thanks for the help @Tobbe :+1:

1 Like

Can you please file an Issue for the wrong TS typing? Shouldn’t have to do // @ts-ignore

Sure

PR included.

2 Likes