Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter how to get data from async function

I am having extreme difficulty in handling this. I call an async function that will get some info from SQLite but I can't seem to get it. It just renders a empty screen in which should be a listview.

List allItems = new List();

Future<void> pegaDados() async {
    var itens = await geraCardapio();
      
    for (var i = 0; i < itens.length; i++) {
        print((itens[i].toMap()));
        allItems.add(itens[i].toMap());
    }
}

print(pegaDados());

return ListView.builder(
    itemCount: allItems.length,
    itemBuilder: (context, index) {
        return ListTile(
            leading: Image.asset("assets/"+ allItems[index]['imagem'], fit: BoxFit.contain,),
            title: Text(allItems[index]['pedido']),
            trailing: Text(allItems[index]['valor']),
        );
    },
);

Thank you very much.

I managed to get the solution, thanks to both people who answered the question (using both solutions I managed to get this little frankenstein)

Future<dynamic> pegaDados() async {
    var allItems = await geraCardapio();

    return allItems.map((allItems) => allItems.toMap());
}

return FutureBuilder(
    future: pegaDados(),
    builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.done) {
            print(snapshot.data);
            var objeto = [];

            for (var i in snapshot.data) {
                objeto.add(i);
            }
              
            print(objeto);
            return Container(
                child: ListView.builder(
                itemCount: objeto.length,
                itemBuilder: (context, index) {
                    return ListTile(
                        leading: Image.asset("assets/"+ objeto[index]['imagem'], fit: BoxFit.contain),
                        title: Text(objeto[index]['pedido']),
                        trailing: Text(objeto[index]['valor'].toString()),
                    );
                },
            ),
        );
    } else if (snapshot.hasError) {
        throw snapshot.error;
    } else {
        return Center(child: CircularProgressIndicator());
    }
});

thanks to [Mohammad Assem Nasser][1] and [Eliya Cohen][2] for the help!

  [1]: https://stackoverflow.com/users/11542171/mohammad-assem-nasser
  [2]: https://stackoverflow.com/users/1860540/eliya-cohen
like image 350
Vitor Araújo Avatar asked Nov 06 '19 00:11

Vitor Araújo


People also ask

How do you get async value in Flutter?

You can get the value like this: SharedPreferences sharedPreferences; Future<String> token() async { sharedPreferences = await SharedPreferences. getInstance(); return "Lorem ipsum dolor"; } token(). then((value) { print(value); });

How do I return from async to Flutter?

Functions marked 'async' must have a return type assignable to 'Future'. Try fixing the return type of the function, or removing the modifier 'async' from the function body. But if the return type is void , the async keyword won't save you from that. The following code works without any error.


1 Answers

You should first understand what is Future operations (Future function in your case). Future operations are the operations which take time to perform and return the result later. To handle this problem, we use Asynchronous functions.

Asynchronous Function let your program continue other operations while the current operation is being performed. Dart uses Future objects (Futures) to represent the results of asynchronous operations. To handle these operations, we can use async/await, but it is not possible to integrate async and await on widgets. So it is quite tricky to handle futures in widgets. To solve this problem flutter provided a widget called FutureBuilder.

In FutureBuilder, it calls the Future function to wait for the result, and as soon as it produces the result it calls the builder function where we build the widget.

Here is how it should be:

class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  List allItems = new List();

  Future<List> pegaDados() async{
    var items = await geraCardapio(); // TODO: Add this function to this class

    for (var i = 0; i < items.length; i++) {
      print((items[i].toMap()));
      allItems.add(items[i].toMap());
    }
  return items;
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(title: Text('Demo')),
      body: FutureBuilder(
        future: pegaDados(),
        builder: (context, snapshot){
          if(snapshot.connectionState == ConnectionState.done){
            return Container(
                child: ListView.builder(
              itemCount: snapshot.data.length,
              itemBuilder: (context, index) {
                return ListTile(
                  leading: Image.asset("assets/"+ snapshot.data[index]['imagem'], fit: BoxFit.contain,),
                  title: Text(snapshot.data[index]['pedido']),
                  trailing: Text(snapshot.data[index]['valor']),
                );
              },
                ),
            );
          }
          else if(snapshot.hasError){
            throw snapshot.error;
          }
          else{
            return Center(child: CircularProgressIndicator());
          }
        },
      ),
    );
  }
}

Here is the link to a short video that will explain FutureBuilder in a concise way.

like image 50
Mohamad Assem Nasser Avatar answered Oct 15 '22 09:10

Mohamad Assem Nasser