flutter_qora 0.3.0
flutter_qora: ^0.3.0 copied to clipboard
A Flutter wrapper around the Qora async state management library, providing seamless integration with Flutter's widget tree and lifecycle
flutter_qora #
Flutter widgets for Qora — bind server state to your UI with a single widget. No setState, no StreamBuilder, no loading flag spaghetti.
Install #
dependencies:
flutter_qora: ^1.0.0
flutter_qoraautomatically includesqoraandconnectivity_plusas dependencies — no extra packages needed.
Setup #
Wrap your app with QoraScope once:
import 'package:flutter_qora/flutter_qora.dart';
void main() {
final client = QoraClient(
config: const QoraClientConfig(debugMode: kDebugMode),
);
runApp(
QoraScope(
client: client,
// Optional: refetch when app resumes or network reconnects
lifecycleManager: FlutterLifecycleManager(qoraClient: client),
connectivityManager: FlutterConnectivityManager(qoraClient: client),
child: const MyApp(),
),
);
}
Fetch and display data #
QoraBuilder<T> fetches on mount, caches the result, and rebuilds on every state change:
QoraBuilder<User>(
queryKey: ['users', userId],
queryFn: () => api.getUser(userId),
builder: (context, state) {
return state.when(
onInitial: () => const SizedBox.shrink(),
onLoading: (previousData) => previousData != null
? UserCard(user: previousData, isRefreshing: true)
: const CircularProgressIndicator(),
onSuccess: (user, updatedAt) => UserCard(user: user),
onError: (error, _, previousData) => ErrorScreen(
message: error.toString(),
onRetry: () => context.qora.invalidate(['users', userId]),
),
);
},
)
Invalidate after a mutation #
// In a button handler, after creating or updating data
await api.createPost(payload);
context.qora.invalidate(['posts']); // Exact key
context.qora.invalidateWhere((k) => k.firstOrNull == 'posts'); // By predicate
Every QoraBuilder subscribed to a matching key re-fetches automatically.
Optimistic updates #
final client = context.qora;
final key = ['users', userId];
// 1. Snapshot for rollback
final snapshot = client.getState<User>(key);
// 2. Update UI instantly
client.setQueryData<User>(key, user.copyWith(name: newName));
try {
// 3. Fire the mutation
final updated = await api.updateUser(userId, newName);
client.setQueryData<User>(key, updated); // Confirm with server data
} catch (_) {
// 4. Roll back on failure
client.restoreQueryData<User>(key, snapshot);
}
Observe without fetching #
QoraStateBuilder<T> mirrors a query's state without triggering a fetch — ideal for badges, counters, or secondary displays:
QoraStateBuilder<List<Notification>>(
queryKey: ['notifications'],
builder: (context, state) {
final count = state.dataOrNull?.length ?? 0;
return Badge(label: Text('$count'), child: const Icon(Icons.notifications));
},
)
Documentation #
Full guides and API reference: qora.meragix.com