Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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);
like image 333
Akash Sarkar Avatar asked Jan 13 '20 08:01

Akash Sarkar


1 Answers

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.

like image 117
Daniel Rearden Avatar answered Sep 27 '22 23:09

Daniel Rearden