Persisting Queries
Implementing offline capabilites by your own can be hard to do (and maintain!!) so Fl-Query makes easier for developers to do it. Fl-Query uses Hive to persist queries to disk. Hive is a Open Source, "lightweight and buzzing-fast key-value database made for Flutter and Dart."
We're using hive because it supports storing unstructured data and the write speed is blazingly fast
But it is planned to support multiple types of Database for persisting using an Adapter pattern
Persisting Queries
Queries can be persisted by passing jsonConfig
argument to the QueryBuilder
or useQuery
. Persisted queries are stored in hive cache and are available even after the app is restarted
First make sure your custom data type is json serializable. You can use json_serializable package to generate toJson
and fromJson
methods for your data type
import 'package:json_annotation/json_annotation.dart';
part 'todo.g.dart';
()
class Todo{
final String id;
final String title;
final bool completed;
Todo({
required this.id,
required this.title,
required this.completed,
});
factory Todo.fromJson(Map<String, dynamic> json) => _$TodoFromJson(json);
Map<String, dynamic> toJson() => _$TodoToJson(this);
}
- Vanilla
- Flutter Hooks
QueryBuilder<Todo, HttpException>(
"todos",
() => api.getTodos(),
jsonConfig: JsonConfig(
fromJson: (json) => Todo.fromJson(json),
toJson: (todo) => todo.toJson(),
),
builder: (context, query) {
/* ... */
},
);
useQuery<Todo, HttpException>(
"todos",
() => api.getTodos(),
jsonConfig: JsonConfig(
fromJson: (json) => Todo.fromJson(json),
toJson: (todo) => todo.toJson(),
),
);
Right now due to lack of reflection support and compile time macros we're unable to serialize any data type on the fly.
That's why JsonConfig
is required. Otherwise, a simple persistToDisk: true
would have been enough
Persisting InfiniteQueries
Just like Query
, InfiniteQuery
also accepts jsonConfig
argument to persist page data to disk. With persisting InfiniteQuery
you can achieve similar results like facebook/twitter's offline mode
- Vanilla
- Flutter Hooks
InfiniteQueryBuilder<PagedPosts, ClientException, int>(
"posts",
(page) => api.getPostsPaginated(page),
nextPage: (lastPage, lastPageData) {
/// returning [null] will set [hasNextPage] to [false]
if (lastPageData.posts.length < 10) return null;
return lastPage + 1;
},
initialPage: 0,
jsonConfig: JsonConfig(
fromJson: (json)=> PagedPosts.fromJson(json),
toJson: (pagedPosts) => pagedPosts.toJson(),
),
builder: /*...*/
);
final query = useInfiniteQuery<PagedPosts, ClientException, int>(
"posts",
(page) => api.getPostsPaginated(page),
nextPage: (lastPage, lastPageData) {
/// returning [null] will set [hasNextPage] to [false]
if (lastPageData.posts.length < 10) return null;
return lastPage + 1;
},
initialPage: 0,
jsonConfig: JsonConfig(
fromJson: (json)=> PagedPosts.fromJson(json),
toJson: (pagedPosts) => pagedPosts.toJson(),
),
);
This will persist each available page to a HiveStore