FutureBuilder stuck at loading while trying to load data from sqflite

329

You are not awaiting for the future here. Add await in the return statement of getHistory().

Future<List<Map<String, dynamic>>> getHistory() async {
    final db = await instance.database; 
    //add await
    return await db?.query('history') as List<Map<String, dynamic>>;
}
Share:
329
Shourya Shikhar
Author by

Shourya Shikhar

Updated on January 03, 2023

Comments

  • Shourya Shikhar
    Shourya Shikhar over 1 year

    I'm using sqflite for storing some data. And using a FutureBuilder to display the data after fetching from the database. But the FutureBuilder failing to return data, is always stuck in the loading screen. This is my database code:

    import 'package:path/path.dart';
    import 'package:sqflite/sqflite.dart';
    
    class HistoryDatabase {
      HistoryDatabase._init();
      static final HistoryDatabase instance = HistoryDatabase._init();
      static Database? _database;
    
      Future<Database?> get database async {
        if (_database != null) {
          return _database;
        } else {
          _database = await getDatabase();  //loads database
          return _database;
        }
      }
    
      void deleteHistory() async {  //deletes data
        final db = await instance.database;
        db?.delete('history');
      }
    
      Future<List<Map<String, dynamic>>> getHistory() async {  //gets database data
        final db = await instance.database;
    
        print(db?.query('history'));
    
        return db?.query('history') as List<Map<String, dynamic>>;
      }
    
      addHistory(String resultExpr, String result) async {  //adds entry
        final db = await instance.database;
        db?.execute(
          'INSERT INTO history (resultExpr, result) VALUES (?, ?)',
          [resultExpr, result],
        );
      }
    
      Future<Database> getDatabase() async {  //database loader method
        return openDatabase(
          join(await getDatabasesPath(), 'calculator.db'),
          onCreate: (db, version) {
            return db.execute(
              'CREATE TABLE history(id INTEGER PRIMARY KEY AUTOINCREMENT, resultExpr TEXT NOT NULL, result TEXT NOT NULL)',
            );
          },
          version: 1,
        );
      }
    }
    

    This is my FutureBuilder widget:

    class _BottomSheetState extends ConsumerState<BottomSheet> {
      @override
      Widget build(BuildContext context) {
        return FutureBuilder<List<Map<String, dynamic>>>(
            future: HistoryDatabase.instance.getHistory(),
            builder: (context, snapshot) {
              if (snapshot.hasData) {
                final history = snapshot.data as List<Map<String, dynamic>>;
                return ListView.builder(
                  itemCount: history.length,
                  itemBuilder: (context, index) {
                    final historyIndex = history[index];
                    return ListTile(
                      title: Text(historyIndex['resultExpr'].toString()),
                    );
                  },
                );
              } else {
                return const Center(
                    child: CircularProgressIndicator(  //the futurebuilder always shows this widget
                  color: Colors.black,
                ));
              }
            });
      }
    }
    

    There's no error or warnings being shown in my editor. Also I'm sure that there's no error in the database initialisation, because my insertion method is working perfectly. What's the mistake I'm making here?

    • Josteve
      Josteve over 2 years
      What does print(db?.query('history')); print?
    • Shourya Shikhar
      Shourya Shikhar over 2 years
      @Josteve it prints Instance of 'Future<List<Map<String, Object?>>>'