TallerWebSolutions / apollo-cache-instorage

Apollo Cache implementation that facilitates locally storing resources
MIT License
96 stars 11 forks source link

React Native: Response not successful #13

Open danilowoz opened 4 years ago

danilowoz commented 4 years ago

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?

lukadriel7 commented 4 years ago

Hey, can you show the query itself ?

danilowoz commented 4 years ago

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 commented 4 years ago

More details:

[GraphQL error]: Message: Cannot query field "__persist" on type "MyType".
lukadriel7 commented 4 years ago

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 commented 4 years ago

@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 commented 4 years ago

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.

danilowoz commented 4 years ago

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

lukadriel7 commented 4 years ago

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 commented 4 years ago

@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
});
sebas5384 commented 4 years ago

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

lukadriel7 commented 4 years ago

@sebas5384 I sent you a message on spectrum

sebas5384 commented 4 years ago

@lukadriel7 hope you received the invitation 😉

ChronSyn commented 4 years ago

@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).

andreasanta commented 4 years ago

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