Error when populating FutureBuilder with data from sqflite

1,287

The method getAllMovies() has no specific return type, so, by default, it will return:

  1. void: if there is no return statement.
  2. dynamic: if there is a return statement. Int if it returns int, String if it returns String...

In your case it is returning a list but dart does not know that until the method is called. The widget FutureBuilder requires a function that needs to explicitly return a List of Movies, not a dynamic.

Just add a List of Movies as a return type to getAllMovies() method and you should be good to go:

 List<Movies> getAllMovies() async {
    final db = await database;
    var res = await db.query("Movie");
    List<Movie> list =
        res.isNotEmpty ? res.map((m) => Movie.fromSqLite(m)).toList() : [];
    return list;
  }
Share:
1,287
Zebrastian
Author by

Zebrastian

Updated on December 15, 2022

Comments

  • Zebrastian
    Zebrastian over 1 year

    I have an SQLite database with movies. I'm following this example.

    I want to show all the movies in a ListView.

    I try to populate the ListView using a FutureBuilder like in the example, but where I assign the future of the FutureBuilder, it throws the following exception:

    type 'Future<dynamic>' is not a subtype of type 'Future<List<Movie>>'
    

    I find this strange as my function that I use in the FutureBuilder returns a List<Movie> and not dynamic.

    What could be causing this error?

    Database:

    class MovieDatabase {
      MovieDatabase._();
      static final MovieDatabase db = MovieDatabase._();
      static Database _database;
    
      Future<Database> get database async {
        if (_database != null) return _database;
        _database = await initDB();
        return _database;
      }
    
      initDB() async {
        Directory documentsDirectory = await getApplicationDocumentsDirectory();
        String path = join(documentsDirectory.path, "MovieDB.db");
        return await openDatabase(path, version: 1, onOpen: (db) {},
            onCreate: (Database db, int version) async {
          await db.execute("CREATE TABLE Movie ("
              ...
              ")");
        });
      }
    
      getAllMovies() async {
        final db = await database;
        var res = await db.query("Movie");
        List<Movie> list =
            res.isNotEmpty ? res.map((m) => Movie.fromSqLite(m)).toList() : [];
        return list;
      }
      ...
    }
    

    Widget:

    @override
      Widget build(BuildContext context) {
        return Center(
          child: Column(
            children: <Widget>[
              FutureBuilder<List<Movie>>(
                future: MovieDatabase.db.getAllMovies(), // This line causes the error
                initialData: List(),
                builder:
                    (BuildContext context, AsyncSnapshot<List<Movie>> snapshot) {
                  return snapshot.hasData
                      ? ListView.builder(
                          itemCount: snapshot.data.length,
                          itemBuilder: (BuildContext context, int position) {
                            Movie movie = snapshot.data[position];
                            return Card(
                              child: ListTile(
                                title: Text(movie.title),
                              ),
                            );
                          },
                        )
                      : Center(
                          child: CircularProgressIndicator(),
                        );
                },
              ),
            ],
          ),
        );
      }
    
  • Zebrastian
    Zebrastian over 4 years
    It had to return a Future<List<Movie>>, but other than that, it works.