Cached Repository
Simple, easy to use and extensible cached repository which can store all you need.
Inspired by NetworkBoundResource for Android.
Show some ❤️ and star the repo to support the project
Resources:
Getting Started
Just create a class with CachedRepository
field and start caching:
class SomeClassRepository {
SomeClassRepository(SomeClassApi someClassApi)
: _cachedRepo = CachedRepository.persistent(
'my_objects',
fetch: (String key, [__]) => someClassApi.getObjects(key),
decode: (json) => SomeClass.listFromJson(json),
cacheDuration: const Duration(hours: 12),
);
final CachedRepository<String, List<SomeClass>> _cachedRepo;
final _logger = Logger();
Stream<Resource<List<SomeClass>>> getMyObjectsStream(
String parameter, {
bool forceReload = false,
}) {
_logger.d('SomeClassRepository => getMyObjectsStream');
return _cachedRepo.stream(parameter, forceReload: forceReload);
}
Future<Resource<List<SomeClass>>> getMyObjects(
String parameter, {
bool forceReload = false,
}) {
_logger.d('SomeClassRepository => getMyObjects');
return _cachedRepo.first(parameter, forceReload: forceReload);
}
Future<void> invalidate(String parameter) {
_logger.d('SomeClassRepository => invalidate');
return _cachedRepo.invalidate(parameter);
}
Future<void> removeObjectFromCache(
String parameter, {
/*required*/ String objectId,
}) async {
_logger.d('SomeClassRepository => removeObjectFromCache');
return _cachedRepo.updateValue(parameter, (list) {
return list.where((it) => it.id != objectId).toList(growable: false);
});
}
Future<void> removeObjectsFromCache(
String parameter, {
/*required*/ List<String> objectIds,
}) async {
_logger.d('SomeClassRepository => removeObjectsFromCache');
return _cachedRepo.updateValue(parameter, (list) {
return list
?.where((it) => !objectIds.contains(it.id))
?.toList(growable: false);
});
}
Future<void> clear(String parameter) {
_logger.d('SomeClassRepository => clear');
return _cachedRepo.clear(parameter);
}
}
class SomeClass {
final String id;
SomeClass(this.id);
factory SomeClass.fromJson(Map<String, dynamic> json) {
return SomeClass(
json['id'],
);
}
Map<String, dynamic> toJson() {
return {
'id': id,
};
}
static List<SomeClass> listFromJson(List<dynamic>/*?*/ jsonList) =>
(jsonList ?? [])
.map((json) => SomeClass.fromJson(json))
.toList(growable: false);
}
abstract class SomeClassApi {
factory SomeClassApi() => _SomeClassFakeApi();
Future<List<SomeClass>> getObjects(String parameter);
Future<void> create(String id);
}
class _SomeClassFakeApi implements SomeClassApi {
final _logger = Logger();
List<SomeClass> myObjects = [
SomeClass('1'),
SomeClass('2'),
SomeClass('3'),
];
@override
Future<List<SomeClass>> getObjects(String parameter) async {
_logger.d('SomeClassFakeApi => getObjects');
await Future.delayed(const Duration(seconds: 1));
return myObjects;
}
@override
Future<void> create(String id) async {
_logger.d('SomeClassFakeApi => create');
await Future.delayed(const Duration(seconds: 1));
myObjects = myObjects
..add(SomeClass(id))
..toList();
}
}
Instead of a SomeClass and SomeClassApi, you can use your own classes.
Feel free to open pull requests.