Persistent state

pub package

Persist state in an Sqlite database across restarts and returns from hibernation. Powered by Sqlcool



PersistentState: constructor parameters:

  • db: an Sqlcool database: see the documentation
  • table: the table to be used for the state. Defailt "state".
  • id: id of the table row to use. Default 1.
  • verbose: verbosity level


init: initialize the state. Run before using it.

onReady: a future that will complete when the state is initialized

mutate: change the value of a key in the persistent state

  • key: the key to modify
  • value: the new value

This method is asynchronous but can not be awaited. The database queries are queued and will be exectuted in order in case of multiple calls to this method.

select: get the value of a key

  • key: the key to get

This method does not hit the database.

dispose: dispose the state once finished using to clean up memory

describe: prints a description of the state


Goal: to persist the current page

Define the state data and initialize the database

In db.dart:

   import 'package:sqlcool/sqlcool.dart';

   Db db = Db();

   DbTable stateTableSchema() {
     /// Define a state table in the database
     /// Documentation about schemas:
     return DbTable("state")..varchar("route", defaultValue: '"/page1"');

   Future<void> initDb() async {
      try {
         await db.init(
            path: "db.sqlite",
            schema: [stateTableSchema()],
            queries: [_populate()]);
         } catch (e) {
      throw ("Can not init db $e");

   String _populate() {
      return 'INSERT INTO state(id) VALUES(1)';

Create the state

In state.dart:

   import 'dart:async';
   import 'package:flutter/material.dart';
   import 'package:persistent_state/persistent_state.dart';
   import 'db.dart';

   AppState state = AppState();

   class AppState {
      PersistentState store;

      Completer _readyCompleter = Completer();

      String get currentRoute =>"route");

      Future<dynamic> get onReady => _readyCompleter.future;

      Future<void> navigate(BuildContext context, String routeName) async {
         // Hit the database to update the route
         store.mutate("route", routeName);
         await Navigator.of(context).pushNamed(routeName);

      Future<void> init() async {
         /// db is an Sqlcool [Db] object
         /// run [initDb] before this
         try {
            store = PersistentState(db: db);
            await store.onReady;
         } catch (e) {
            throw ("Can not create persistent state $e");

Init state

   void main() {
      initDb().then((_) => state.init());

   // later
   await state.onReady;
   // or
   state.onReady.then((_) => doSomething());

Use the state

Calling navigate from anywhere will persist the state of the current route

   state.navigate(context, "/page3");