Apollo-ios: Watch does not call callback on cold cache start

Created on 26 Jun 2017  路  4Comments  路  Source: apollographql/apollo-ios

Hi
I'm using Apollo-iOS beta0.6.0.
Is the following behaviour expected?

  1. No cached data. App is started.
  2. Initialise a callback using watch with returnCacheDataDontFetch
apollo.watch(query: spacesQuery, cachePolicy: .returnCacheDataDontFetch , resultHandler: { (result , error ) in
            if let error = error {
                print(#function, "ERROR | An error occured: \(error)")
                return
            }

            guard let edges  = result?.data?.node?.asAccount?.spaces?.edges else {                  
                print(#function, "ERROR | Could not retrieve trainer")
                return
            }

            completionBlock(result,nil)
        })
  1. Query the graphql endpoint using fetch fetchIgnoringCacheData
     apollo.fetch(query: spacesQuery, cachePolicy: .fetchIgnoringCacheData, resultHandler: { (result , 
         error ) in
            if let error = error {
                print(#function, "ERROR | An error occured: \(error)")
                return
            }
            guard let _ = result?.data?.node?.asAccount?.spaces?.edges else {
                print(#function, "ERROR | Could not retrieve trainer")
                return
            }
        })
  1. Watch callback was not fired
  2. On next app launch watch is called correctly once we've data in cache.
    If the above is correct, what would be the recommended solution so that watch fires correctly after a fetch call is made when data is initially retrieved.
caching

Most helpful comment

Thanks for replying. It would be good if watcher notifies on any cache updates. As I see above is valid case, I'm using watcher only for loading/watching cached data changes, and fetch gets data from network.

As an alternative approach I'm thinking something like this.

  1. fetch using returnCacheDataDontFetch and check for any cached data.
  2. if there is no data then fetch from network and on successful result render UI and setup watcher.
  3. Next time watcher will be automatically called and updates UI.

All 4 comments

Do you store the GraphQLQueryWatcher you get from apollo.watch() somewhere? If not, the watcher will be immediately deinitialized.

See FrontPage app for an example.

Yes I'm storing GraphQLQueryWatcher in class level variable. It calls once I've fetched data.
Here are the steps for visualization purpose.

  1. No data in the cache
  2. Watch callback not called
  3. fetch data from network ( watch does not called )
  4. Launch app next time
  5. watch callback called
  6. fetch data from network ( watch callback called )

Ah, I think this is actually expected behavior (although we may want to rethink it). Basically, a watcher works by watching for a set of dependent keys. But it can only get these keys if it gets at least one valid response (either from the cache or from the network). Because your watch uses .returnCacheDataDontFetch, and the cache is initially empty, it will never get a valid response in that case.

Thanks for replying. It would be good if watcher notifies on any cache updates. As I see above is valid case, I'm using watcher only for loading/watching cached data changes, and fetch gets data from network.

As an alternative approach I'm thinking something like this.

  1. fetch using returnCacheDataDontFetch and check for any cached data.
  2. if there is no data then fetch from network and on successful result render UI and setup watcher.
  3. Next time watcher will be automatically called and updates UI.
Was this page helpful?
0 / 5 - 0 ratings

Related issues

StanislavCekunov picture StanislavCekunov  路  3Comments

Robuske picture Robuske  路  3Comments

farice picture farice  路  4Comments

maxsz picture maxsz  路  4Comments

AnthonyMDev picture AnthonyMDev  路  4Comments