Akash Sarkar
Akash Sarkar

Reputation: 682

apollo client returning undefined in initial reload in react native

I'm trying to fetch some data from my cache. In initial reload data prop returns undefined but if I fast reload the app (react native fast reload) data prop has the value I want. I can not understand why it is returning undefined in initial reload. One case might be I'm calling the query before the cache is initialised. I have consoled the local cache and it shows values but the query is retuning undefined.

My client setup in client.js

const dev = {
  base_url: BASE_URL
};

const httpLink = createHttpLink({
  uri: dev.base_url
});

const errorLink = onError(({ graphQLErrors, networkError, response }) => {
  if (graphQLErrors) {
    // do something with graphql error
    console.log(graphQLErrors);
  }
  if (networkError) {
    // do something with network error
    console.log(networkError);
    // console.log('network not available');
  }
  if (response) {
    console.log(response);
  }
});
const cache = new InMemoryCache();

const setupPersistedCache = async () => {
  const persistor = new CachePersistor({
    cache,
    storage: AsyncStorage
  });

  // Read the current schema version from AsyncStorage.
  const currentVersion = await AsyncStorage.getItem(SCHEMA_VERSION_KEY);

  console.log('currentVersion', currentVersion);

  if (currentVersion && currentVersion === SCHEMA_VERSION) {
    // If the current version matches the latest version,
    // we're good to go and can restore the cache.
    console.log('not migrating cache');
    await persistor.restore();
  } else {
    // Otherwise, we'll want to purge the outdated persisted cache
    // and mark ourselves as having updated to the latest version.
    console.log('migrating cache');
    await persistor.purge();
    await AsyncStorage.setItem(SCHEMA_VERSION_KEY, SCHEMA_VERSION);

    cache.writeData({
      data: {
        ...initialState
      }
    });

    await persistCache({
      cache,
      storage: AsyncStorage,
      debug: true
    });
  }
  // console.log(cache.data);
};

setupPersistedCache();

const link = ApolloLink.from([errorLink, httpLink]);

const client = new ApolloClient({
  defaults: initialState,
  link,
  cache,
  resolvers
});

export default client;

My initialState.js

export default {
  language: 'bd'
};

My index.js

const AppProvider = () => {
  const [loaded, setLoaded] = useState(false);

  const configureCache = async () => {
    try {
      const cache = new InMemoryCache();
      await persistCache({
        cache,
        storage: AsyncStorage,
        debug: true
      });
      console.log(cache.data);
    } catch (error) {
      console.error('Error restoring Apollo cache', error);
    }
  };

  useEffect(() => {
    configureCache()
      .then(() => {
        setLoaded(true);
      })
      .catch(() => {
        setLoaded(false);
      });
  }, []);
  useEffect(() => {
    SplashScreen.hide();
  }, []);

  return (
    <>
      {loaded ? (
        <ApolloProvider client={client}>
          <Root />
        </ApolloProvider>
      ) : (
        <View style={{
          flex: 1,
          justifyContent: 'center',
          alignItems: 'center'
        }}
        >
          <TextComponent
            content="Loading"
            size={fonts.fs24}
            family={fonts.medium}
            color={colors.white}
          />
        </View>
      )}
    </>
  );
};

AppRegistry.registerComponent(appName, () => AppProvider);

My query

export const getLangQuery = gql`
  query getLang {
    language @client
  }
`;

I'm trying to get the data like this in my root page.

const { loading, error, data } = useQuery(getLangQuery);
  const [setLanguage, result] = useMutation(setLangQuery);

  const language = data;
  console.log(language);

Upvotes: 4

Views: 3035

Answers (2)

Akash Sarkar
Akash Sarkar

Reputation: 682

I figure it out myself. I was initialising the persistCache multiple time.Once in client.js and once in index.js. Thats why it was behaving weirdly. Now Everything is behaving as expected.

Upvotes: 0

Daniel Rearden
Daniel Rearden

Reputation: 84687

data is always initially undefined, even if the result is fetched from the cache instead of the server. Once the data is loaded, its persisted in component state, so even if the component rerenders, the data does not have to be fetched from the cache again. A Fast Refresh just triggers a rerender -- it does not reload your whole app -- so any component state, including data in this case, is persisted.

Upvotes: 6

Related Questions