Skip to content

Accessing cached state for conditional refresh validation with persist() #4398

@pckimlong

Description

@pckimlong

Long time ago I did implement a custom riverpod offline support for an app. But now since riverpod has that built-in I want to migrate to official API. But somehow it not allow me to easy maintain existing logic. My old implementation allow to check custom criterial on cached data to decide whether to refresh:

@riverpod
class RadioList extends _$RadioList {
  @override
  FutureOr<IList<RadioModel>> build() {
    const staleDuration = Duration(hours: 6);

    return persistState(
      fetchFreshData: () async { /* ... */ },
      fetchPersistedData: () async { /* ... */ },
      persistData: (data) async { /* ... */ },
      shouldFetchFreshData: (persistedData) async {
        final cache = ref.read(cacheManagerProvider);
        final time = await cache.readDateTime(cachedStaleKey);

        final isStale =
            persistedData.isEmpty ||
            time == null ||
            time.isBefore(DateTime.now().subtract(_expiredIn));
        return isStale;
      },
    );
  }
}

With riverpod persist(), I can use destroyKey to force refresh, but I'd need to access the cached data from Riverpod to decide when to bump it, and that's not easily accessible.

Proposed solution:
A callback like shouldRefresh: (cachedData) async in StorageOptions would allow to check the state itself:

options: StorageOptions(
  shouldRefresh: (cachedData) async {
    final cache = ref.read(cacheManagerProvider);
    final time = await cache.readDateTime(cachedStaleKey);
    return cachedData.isEmpty || time?.isBefore(...) ?? true;
  },
),

Or Is there an existing pattern for this?

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions