2

I want to get all the items from the database, but i am stuck how to convert the Future list of strings to list of strings.

var x =  DataBaseHelper.instance.queryAllRows();


 Future<List<String>> queryAllRows() async {
    Database db = await instance._initDatabase();
    List<Map<String,dynamic>> s =  await db.query(table ,columns: [columnname]);
    List<String> list = new List();
    for(var x in s){
      x.forEach((k,v)=>list.add(v));
    }
    return list;
 }

I want to get all the values in the database but dont know how to convert those values to the List

Gopal Awasthi
  • 423
  • 1
  • 6
  • 15
  • To get from your `List>` to a `List` with all the values in all the maps you could do: `var list = List.from(s.expand((m) => m.values))` – Nate Bosch Jul 10 '19 at 22:21
  • Please see my post at: https://stackoverflow.com/a/63082129/7681696 – GtdDev Jul 24 '20 at 22:34
  • @NateBosch I followed your suggestion but getting an error "The argument type 'Future>' can't be assigned to the parameter type 'Iterable'". Thank you. – Kamlesh Aug 08 '20 at 17:13
  • @Kamlesh my comment is about the handling the types _other_ than the asynchronous bit. See the answers below for information about handling a `Future`. See also https://dart.dev/codelabs/async-await – Nate Bosch Aug 10 '20 at 17:33

4 Answers4

2

You need an asynchronous function to retrieve the data.

void yourFunction() async {
     var x =  await DataBaseHelper.instance.queryAllRows();

}
diegoveloper
  • 93,875
  • 20
  • 236
  • 194
2

You have two of choices. You can use future builder to create widgets or use plain futures + setState

https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html

https://dart.dev/tutorials/language/futures

https://api.flutter.dev/flutter/widgets/State/setState.html

List<String> _databaseList

queryAllRows().then((rows) {

   setState(() {_databaseList = rows});
})

setState will tell the flutter to rebuild the widget tree. then to process the future.

user1462442
  • 7,672
  • 1
  • 24
  • 27
1

Because db.querys are asynchronous, they are going to return a Future<List<Map<String,dynamic>>. To get their result without a future, we can get a call back and it will return a List<Map<String,dynamic>> instead.

var x =  DataBaseHelper.instance.queryAllRows();

  Future<List<String>> queryAllRows() async {
    Database db = await instance._initDatabase();
    db.query(table ,columns: [columnname]).then((data){
      List<Map<String,dynamic>> s = data;
      List<String> list = new List();
      for(var x in s){
        x.forEach((k,v)=>list.add(v));
      }
    });
    return list;
  }
sfung3
  • 2,227
  • 1
  • 9
  • 30
  • Sorry dear, this solution did not work for me and was resulting me an error "Instance of 'Future>'" in debug console. Thanks. – Kamlesh Aug 08 '20 at 16:49
0

You need to await the queryAllRows() to complete. If you are in the context of a function that can be marked as async just need to use the keyword :

void someFunction() async {
var x =  await DataBaseHelper.instance.queryAllRows(); // x is List<String>
}

Instead, if you want to render the list you can use the FutureBuilder and manage the render widget based on Future state :

Widget test(BuildContext context) {
  return FutureBuilder<List<String>>(
    future: DataBaseHelper.instance.queryAllRows(),
    builder: (context, snap) {
      if (snap.hasData && !snap.hasError) {
        return ListView(
          padding: const EdgeInsets.all(8.0),
          children: <Widget>[...snap.data],
        );
      }
      else {
        return Container();
      }
    },
  );
}
fvillalba
  • 963
  • 10
  • 18