apollo-cache-instorage icon indicating copy to clipboard operation
apollo-cache-instorage copied to clipboard

React Native: Response not successful

Open danilowoz opened this issue 5 years ago • 14 comments

Hey, nice to see this elegant solution for persisting data, but I'm facing some issue on React Native implementation.

My Apollo client configuration:

  import AsyncStorage from '@react-native-community/async-storage';

  const cache = new InStorageCache({
    addPersistField: true,
    shouldPersist: PersistLink.shouldPersist,
    storage: AsyncStorage,
    denormalize: async result => {
      const data = await result;
      return JSON.parse(data);
    },
  });

  const link = ApolloLink.from([
    new PersistLink(),
    createHttpLink({ uri: API }),
  ]);

  const client = new ApolloClient({
    cache,
    link,
  });

Problem: On the first query, I'm not using the directive @persist, then I'm getting the following message on the simulator:

Screenshot 2020-02-06 at 17 28 46

And even if I add the directive, it still doesn't save the data. Any idea about it?

danilowoz avatar Feb 06 '20 17:02 danilowoz

Hey, can you show the query itself ?

lukadriel7 avatar Feb 06 '20 20:02 lukadriel7

Sure, the following query works, but without persist data:

  query MyQuery {
    pokemon(name: "Bulbasaur") @persist {
      name
    }
  }

And this one returns an error (like the print screen):

  query MyQuery {
    pokemon(name: "Bulbasaur") {
      name
    }
  }

danilowoz avatar Feb 07 '20 09:02 danilowoz

More details:

[GraphQL error]: Message: Cannot query field "__persist" on type "MyType".

danilowoz avatar Feb 07 '20 11:02 danilowoz

Hey from the tests I made, the addPersistField is the one triggering the error. Removing it allows for queries to work but there is no persistence. Keeping it forces the use of @persist for queries to work which is the same as not using The PersistLink at all. The author of this package also seems really busy and doesn't have time to work on it. Great package but with no support at the moment. It's a shame the guys behind apollo don't take a interest in this. The most up-to-date fork I have seen is this. You can also find it on npm. Unfortunately it seems to have the same problem. @MartijnHols maybe you could help us ?

lukadriel7 avatar Feb 07 '20 15:02 lukadriel7

@danilowoz it would seem that the @persist directive has to exist for at least one field in your query for it to be valid. It is weird but the this package doesn't seem to take into account the possibility of making a request without persistence

lukadriel7 avatar Feb 07 '20 17:02 lukadriel7

I think I found the problem. In the implementation of PersistLink in the request function, there is an early exit if there is no @persist directive found. Commenting out the exit condition fixes the problem. @MartijnHols if you see this can you please make the change in your package ? @lucasconstantino can you give me writing access to the repository ? I may not be able to develop full time but I think that I can help with pull request and other small changes.

lukadriel7 avatar Feb 07 '20 18:02 lukadriel7

Hey @lukadriel7 I have tested what you said and I'm not getting the Error status code 400 anymore, but the query still doesn't persist on my storage.

Thanks for debugging

danilowoz avatar Feb 10 '20 09:02 danilowoz

Hey @lukadriel7 I have tested what you said and I'm not getting the Error status code 400 anymore, but the query still doesn't persist on my storage.

Thanks for debugging

I think that might be because this package doesn't natively support asynchronous storage options. You have to implement at least the denormalize part. Not sure about normalize, I haven't tried yet.

lukadriel7 avatar Feb 10 '20 09:02 lukadriel7

@danilowoz This is the code I used for localforage. Not sure if it is perfect but it works for both localforage(async) and localstorage(sync).

const cache = new InStorageCache({
  storage: localForage,
  denormalize: value => {
    if (value == null) {
      return value;
    } else {
      if (typeof value.then == "function") {
        value
          .then(data => {
            return JSON.parse(data);
          })
          .catch(() => null);
      } else {
        return JSON.parse(value);
      }
    }
  },
  addPersistField: true,
  shouldPersist: PersistLink.shouldPersist
});

lukadriel7 avatar Feb 10 '20 11:02 lukadriel7

hey guys! good to see this lib is being used in React Native.

@lukadriel7 could you ping me at twitter or spectrum.chat to give you write permissions? my handler is the same @sebas5384

sebas5384 avatar Feb 17 '20 21:02 sebas5384

@sebas5384 I sent you a message on spectrum

lukadriel7 avatar Mar 03 '20 00:03 lukadriel7

@lukadriel7 hope you received the invitation 😉

sebas5384 avatar Mar 03 '20 18:03 sebas5384

@lukadriel7 @sebas5384 @danilowoz

Just curious if anyone made any progress with this. I'm having the issue that my data is persisting in AsyncStorage as expected, but the value of the data property in useQuery always returns undefined.

For example, this correctly shows the data in storage;

AsyncStorage.getAllKeys().then(data => {
  console.log("Data from async", data)
})

AsyncStorage.getItem("ROOT_QUERY", (err, result) => {
  console.log("keyed data from async", result)
})

I've tried calling with and without cache.restore(). I've also tried several different forks of this library, and none of them seem to have fixed this issue. I'm having to use this library because the apollo-cache-persist library caches everything, including both local state such as user settings, and API data which I don't want to cache (due to the data only being relevant for a short time and being a very large data set).

ChronSyn avatar Apr 07 '20 21:04 ChronSyn

We've tried with the code submitted above by @lukadriel7 , but we get one error:

message: "Cannot query field "__persist" on type "Championship"."

And lots of warnings, attached screenshot.

image (4)

@danilowoz Could you ever run it successfully on React Native?

Thanks, A

andreasanta avatar May 20 '20 11:05 andreasanta