react-apollo icon indicating copy to clipboard operation
react-apollo copied to clipboard

Unhandled Rejection (TypeError): Cannot read property 'refetch' of undefined

Open tronxdev opened this issue 4 years ago • 26 comments

Hello friends,

Today I faced an issue with GraphQL in my React.js project. What I tried to do is refetch a query once a mutation is completed. My codebase is as below

const getUserTeamQuery = useQuery(getUserTeam(usersFragment))
const data = get(getUserTeamQuery, 'data.getUserTeam')

const [updateUser] = useMutation(updateUserMutation(usersFragment), {
  onCompleted: () => {
    getUserTeamQuery.refetch()
  }
})

const updateTeam = async () => {
  updateUser({ variables: { input: { pullTeam } } })
}

Image error

Is there any solution to fix the issue?

tronxdev avatar Feb 27 '20 13:02 tronxdev

Hi @proIT324, I just faced the same issue. It was because my component was unmount before the call of refetch. Maybe you have a side effect caused by your mutation which unmount the component were you call your useQuery ?

jean9696 avatar Mar 04 '20 09:03 jean9696

I noticed the same thing while building a logout function that calles cache.reset(). Maybe this leads to an invalid state internally.

EyMaddis avatar Mar 05 '20 14:03 EyMaddis

Was running into the same issue, but noticed that it only appears after a Live Reload. Works just fine after a full reload.

alradadi avatar Mar 12 '20 20:03 alradadi

I am experiencing this as well in React Native when trying to refetch when the subscription client reconnects

SubscriptionClient.onReconnected(() => {
      refetch()
})

This works fine when the component loads initially. However, if I navigate to the previous screen, then back to the screen with the subscription _this.currentObservable is an empty object in

_this.obsRefetch = function (variables) {
      return _this.currentObservable.query.refetch(variables);
};

thus, query is undefined.

forbesgillikin avatar Mar 26 '20 03:03 forbesgillikin

I am experiencing the same problem. When I am loading my screen for the first time, my FlatList pull to refresh is working. After editing my screen.js file and saving it, right after that i will get this failure. I am also using chrome debug with fast refresh enabled.

error screenshot

This is my FlatList:

            <FlatList
              data={data.users}
              renderItem={({ item }) => (
                <Item
                  id={item.id}
                  username={item.username}
                  email={item.email}
                  role={item.role}
                  // eslint-disable-next-line react/prop-types
                  selected={!!selected.get(item.id)}
                  onSelect={onSelect}
                />
              )}
              extraData={data}
              keyExtractor={(item) => item.id}
              // keyExtractor tells the list to use the ids for the react keys instead of the default key property.
              refreshing={networkStatus === 4}
              // As long as networkStatus is 4 (true) refetching is in progress. It has to be true, otherwise refetch will not work.
              onRefresh={() => refetch()}
            />

cryptedx avatar Mar 29 '20 14:03 cryptedx

I am having the same problem in web React (Create React App and Typescript) with Fast Refresh. If a refetch happens after a fast refreshed change, it just crashes with this error. Would it be possible to fix it? It is probably not a production issue, but it is a huge annoyance when developing an app.

danieldunderfelt avatar Apr 15 '20 02:04 danieldunderfelt

Indeed, it's so annoying. I always have to completely restart the app. Please please is a fix possible?

cryptedx avatar Apr 15 '20 06:04 cryptedx

This also happens with Hermes in React Native, every time we save a file and triggers a refresh, refetching will throw.

I am using @apollo/[email protected]

vicary avatar Apr 20 '20 20:04 vicary

The annoying thing is, this happens to us on production as well in combination with CodePush. Whenever a new version is updated the app will restart and voila, the whole app crashes because Apollo refetch is unavailable.

callaars avatar May 07 '20 09:05 callaars

I thought it could be a problem because I had declared some anon functions. I fixed that but problem is still occurring.

cryptedx avatar May 08 '20 08:05 cryptedx

I currently am working around this like so:

const { data, refetch } = useQuery(...) || {}

EDIT:

This didn't actually work :(

briangonzalez avatar May 12 '20 16:05 briangonzalez

I'm using NextJS. I got the same error after upgrade to next 9.4, it happened after React refresh implemented by NextJS.

oknoorap avatar May 13 '20 14:05 oknoorap

Use link not url in the configuration

`import { ApolloClient } from '@apollo/client';

import { InMemoryCache } from 'apollo-cache-inmemory'; import { HttpLink } from 'apollo-link-http';

const client = new ApolloClient({ cache: new InMemoryCache({ addTypename: true }), link: new HttpLink({ uri: 'http://192.168.1.39:4000' }) });

export default client;`

daviddionis avatar May 14 '20 10:05 daviddionis

I stumbled upon the same problem and it looks like the culprit is the ! operator in Apollo's code:

image

derekstavis avatar May 14 '20 17:05 derekstavis

@derekstavis Is it some kind of pre-draft babel for optional chaining (?.)?

vicary avatar May 15 '20 12:05 vicary

It's typescript, @vicary

callaars avatar May 15 '20 12:05 callaars

^ https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-0.html#non-null-assertion-operator

ethanIncentify avatar May 15 '20 12:05 ethanIncentify

A quick fix is to wrap it in setTimout like so:

const refetch = useCallback(() => { setTimeout(() => _refetch(), 0) }, [_refetch])

maxb94 avatar May 17 '20 20:05 maxb94

@callaars It was meant to be a joke but it pulled off poorly I guess, the use optional chaining would at least make it not crash.

vicary avatar May 18 '20 04:05 vicary

A quick fix is to wrap it in setTimout like so:

const refetch = useCallback(() => { setTimeout(() => _refetch(), 0) }, [_refetch])

const {loading, error, data} = useQuery(VIEW_ALL_COMMENTS); const _refetch = useQuery(VIEW_ALL_COMMENTS).refetch; const refetch = useCallback(() => { setTimeout(() => _refetch(), 0) }, [_refetch]);

This code works! Thanks, maxb94!!

wooogler avatar May 18 '20 13:05 wooogler

Same issue as others, NextJS 9.4 which implements React's native live reload (instead of hot module reload). The only solution is the one proposed by @maxb94

@wooogler a better way to do that is this

const {loading, error, data, refetch: _refetch} = useQuery(VIEW_ALL_COMMENTS);
const refetch = useCallback(() => { setTimeout(() => _refetch(), 0) }, [_refetch]);

tm1000 avatar May 19 '20 21:05 tm1000

FYI: https://github.com/apollographql/apollo-client/issues/5870

tm1000 avatar May 19 '20 22:05 tm1000

@tm1000 Thanks for taking my joke seriously, I guess. I have no idea about the inner workings, it was just a patchy-patch attitude. 😄

vicary avatar May 23 '20 09:05 vicary

Is this issue being looked at or abandoned? or do we wait for v4.0 ?

peitalin avatar Jun 21 '20 08:06 peitalin

^

santaclauze avatar Jun 22 '20 03:06 santaclauze

^^

grantspeelman avatar Jun 26 '20 11:06 grantspeelman