Asynchronous function with Futurebuilder returning a list of Widgets

Asked

Viewed 280 times

1

My function was to obtain data from a system and mount the widgets. It was synchronous and works perfectly.

  children: _confere
      .obterDados(data)
      .map(
        (d) => Conferencia(
          dados: d,
        ),
      )
      .toList()

Now the need arose to make it asynchronous. Then came the headache with FutureBuilder.

I tried several ways to iterate on the result and return a list of wigets, but without success.

The closest I could get was with the code below:

children: <Widget>[
FutureBuilder(
  future: _confere.obterDados(data),
  builder: (_, AsyncSnapshot<ObservableList<Dados>> snapshot) {
    if (snapshot.hasData) {
      return Conferencia(dados: snapshot.data[2]);
    } else {
      return (Text('consultando'));
    }
  },
  ),
],

Obviously, in this code only a single result is returned. I would like to know how to return the iteration result using FutureBuilder. Most of the examples I’ve seen only return widget single and never, a list.

  • If your snapshot.data is a list and you also expect a list, you could create a new variable within the Builder function and with a repeat loop go through the snapshot and populate the variable. Then you could return this list inside your widget. You thought of something like?

  • @Leonardopaim tried, but when I try to return a list shows the err: The Return type 'List<Widget>' isn’t a 'Widget', as required by the closure’s context.acredito que devido<Widget>[ If removed <Widget> and leave return as List<Widget> The argument type 'Futurebuilder<Observablelist<Data>>' can’t be Assigned to the Parameter type 'List<Widget>

  • @Leonardopaim found a solution based on his information, but creating a new function Future<List<Widget>> _widgets() async {, I’ll wait if you want to post an answer, otherwise I’ll put the solution I found.

  • No problem, post the solution that worked for you. Initially my suggestion was something generic so that I could direct you to the specific answer of your problem. Since Stack values effective answers to specific problems, it is best that you leave to the community the solution you applied and solved the problem you were initially.

1 answer

1


I saw that you have already found a solution, but only to leave one more possibility of how it can be done:

FutureBuilder(
  future: _conferencia.obterDados(data),
  builder: (_, AsyncSnapshot<ObservableList<Dados>> snapshot) {
    if (!snapshot.hasData)
      return Center(child: Text("Carregando dados!"));

    return SeuWidget(
      children: snapshot.data.map((item){
        return Conferencia(dados: item);
      }).toList()
    );

  },
),

Explanation

The FutureBuilder has the function of waiting for the data from some source and then when owning the data it will re-build, but while the data does not arrive you can inform the user that something is happening, then that’s why I do the following validation

if (!snapshot.hasData) {
  return Center(child: Text("Carregando dados!"));

So until the data arrives, we inform the user that we are waiting or loading the information!

  • Exactly that! But this one return Container(); has some function?

  • Future will build only when it has data... So as long as there’s no dice he’ll build a blank, or better you can put yours Text("Carregando...") to inform that it is expecting some data. I adjusted the answer, of a glance!

  • There is a lack of if (!snapshot.hasData) { or is not closing the { to return return SeuWidget(

  • 1

    Oops! My fault, I didn’t see the key open there, just remove it. ~~ I didn’t get to test, I’m without Flutter on the machine.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.