Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter: type 'Future<dynamic>' is not a subtype of type 'Widget'

I am using sqlite to store data in my Flutter App. I have a modal bottomsheet which opens with filterchips and when you select one it adds the item to the database. If the item already exists the filterchip is checked. When I call the database function to check if the item already exist I get the below error.

I have tried using both async and await.

Database query code:

// FIND TAG
findTag(int tagId) async {
    var dbConnection = await db;
    var res = await  dbConnection.query("$TABLE_NAME", where: "tagId = ?", whereArgs: [tagId]);
    return res.isNotEmpty ? true : false ;
  }

Modal bottomsheet widget container code:

Widget build(BuildContext context) {
    setState(() {
      _index = widget.index;
      _list =widget.list;
    });

    return new Container(
      padding: new EdgeInsets.all(27.0),
      child: new Column(
        mainAxisAlignment: MainAxisAlignment.start,
        mainAxisSize: MainAxisSize.min,              
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget> [
          new Text(_list[_index]["title"], style: new TextStyle(  fontWeight: FontWeight.bold, fontSize: 22),),          
          new Text(_list[_index]["description"]),
          getFilterChipsWidgets(),
        ],
      ),
    );

}


getFilterChipsWidgets()
  async {

    List<Widget> tagsList = new List<Widget>();
      for(var i=0; i<_list[_index]["tags"].length; i++) {       
        var dbHelper = DBHelper();
        int id = int.parse(_list[_index]["tags"][i]["id"]);

        var exist = await dbHelper.findTag(id);
        FilterChip item = new FilterChip(
          label: Text(_list[_index]["tags"][i]["name"].toString(),), 
          selected: exist,
          onSelected: (bool newValue) {
            if(newValue) {
              dbHelper.addNewTag(id);
            } else {
              dbHelper.deleteNewTag(id);
            }
          },
        );
        tagsList.add(item);       
      }

       return Wrap(
          spacing: 8.0, // gap between adjacent chips
          runSpacing: 4.0, // gap between lines
          children: tagsList,
        );
}


like image 470
Niru Avatar asked Mar 27 '19 13:03

Niru


2 Answers

Your getFilterChipsWidgets() is async function so it will return Future. You could await for the future and save widgets to list and call setState once it is compleated. Or just wrap it with FutureBuilder like so:

    children: <Widget> [
      new Text(_list[_index]["title"], style: new TextStyle(fontWeight: FontWeight.bold, fontSize: 22),),          
      new Text(_list[_index]["description"]),
      FutureBuilder<Widget>(
       future: getFilterChipsWidgets,
       builder: (BuildContext context, AsyncSnapshot<Widget> snapshot){
         if(snapshot.hasData)
           return snapshot.data;

         return Container(child: CircularProgressIndicator());
       }
      ),
    ],
like image 143
knezzz Avatar answered Sep 23 '22 14:09

knezzz


Sometimes it also has been seen, that mistakenly you have assigned the function async and inside the function block no where you are using the await processes,

Similar scenario have been already happened with me, and by removing this unused async over the function resolved this above issue.

when you make any function async, the function requester treats that in Future<T> way, so be careful.

like image 23
ArifMustafa Avatar answered Sep 23 '22 14:09

ArifMustafa