Perform Async Operations from Data gotten from StreamBuilder before displaying

Viewed 1025

I am currently using StreamBuilder to get data from Firestore and so far, it is working good.

I currently want to perform some async operations to the data before displaying.

The code to get the data is below.

    List<Model> listToDisplay = new List<Model>();

      @override
      Widget build(BuildContext context) {    
    return DefaultTabController(
    length: 2,
    child: Scaffold(
        appBar: topBar,
        body: StreamBuilder(
            stream: Firestore.instance.collection('/myPath').snapshots(),
            builder: (BuildContext context,
                AsyncSnapshot<QuerySnapshot> snapshot) {
              if(snapshot.connectionState == ConnectionState.active) {
                listToDisplay.clear();
                for (DocumentSnapshot _snap in snapshot.data.documents) {
                  Model _add = new Model.from(_snap);
                  listToDisplay.add(_add);
                }
                return TabBarView(
                  children: <Widget>[
                    ListView.builder(
                      itemCount: mouveList.length,
                      itemBuilder: (context, index) {
                        return Card(listToDisplay[index]);
                      },
                    ),
                    Icon(Icons.directions_transit),
                  ],
                );
              } else {
                return Container(
                    child: Center(child: CircularProgressIndicator()));
              }
            })));

I tried adding the async operation in the for in loop but that did not work, it did not wait for it. Also, add await did not work because Widget build(BuildContext context) cannot be async.

      @override
      Widget build(BuildContext context) {    
    return DefaultTabController(
    length: 2,
    child: Scaffold(
        appBar: topBar,
        body: StreamBuilder(
            stream: Firestore.instance.collection('/myPath').snapshots(),
            builder: (BuildContext context,
                AsyncSnapshot<QuerySnapshot> snapshot) {
              if(snapshot.connectionState == ConnectionState.active) {
                listToDisplay.clear();
                for (DocumentSnapshot _snap in snapshot.data.documents) {
                  Model _add = new Model.from(_snap);
                  //Added
                  //_add.getCalculate(); <------- Async function
                  _add.Calculate(); <------ Flutter does not wait for this
                 await _add.Calculate(); <------ Produces an error

                 listToDisplay.add(_add);
                }
                return TabBarView(
                  children: <Widget>[
                    ListView.builder(
                      itemCount: mouveList.length,
                      itemBuilder: (context, index) {
                        return Card(listToDisplay[index]);
                      },
                    ),
                    Icon(Icons.directions_transit),
                  ],
                );
              } else {
                return Container(
                    child: Center(child: CircularProgressIndicator()));
              }
            })));

Any ideas on how to get data as stream, perform operations on the data before displaying the data all using StreamBuilder and ListViewBuilder ?

1 Answers

I'm currently iterating the data from a StreamBuilder in corresponding lists and then using a ListView.builder to display each data item from List.count. The code begins with these public/file Lists...

List names = new List();
List ids = new List();
List vidImages = new List();
List numbers = new List();

Then this in my Stateful Widget Builder...

child: new StreamBuilder(
                      stream:
                          fb.child('child').orderByChild('value').onValue,
                      builder:
                          (BuildContext context, AsyncSnapshot<Event> event) {
                        if (event.data?.snapshot?.value == null) {
                          return new Card(
                            child: new Text(
                                'Network Error, Please Try again...',
                                style: new TextStyle(
                                    fontSize: 12.0,
                                    fontWeight: FontWeight.bold,
                                    fontStyle: FontStyle.italic)),
                          );
                        } else if (event.data?.snapshot?.value != null) {
                          Map myMap =
                              event.data?.snapshot?.value; //store each map

                          var titles = myMap.values;

                          List onesTitles = new List();
                          List onesIds = new List();
                          List onesImages = new List();
                          List onesRank = new List();

                          List<Top> videos = new List();

                          for (var items in titles) {
                            var top = new Top(
                                videoId: items['vidId'],
                                rank: items['Value'],
                                title: items['vidTitle'],
                                imageString: items['vidImage']);
                            videos.add(top);
                            videos..sort((a, b) => b.rank.compareTo(a.rank));
                          }

                          for (var vids in videos) {
                            onesTitles.add(vids.title);
                            onesIds.add(vids.videoId);
                            onesImages.add(vids.imageString);
                            onesRank.add(vids.rank);
                          }

                          names = onesTitles;
                          ids = onesIds;
                          numbers = onesRank;
                          vidImages = onesImages;

                          switch (event.connectionState) {
                            case ConnectionState.waiting:
                              return new Card(
                                child: new Text('Loading...',
                                    style: new TextStyle(
                                        fontSize: 12.0,
                                        fontWeight: FontWeight.bold,
                                        fontStyle: FontStyle.italic)),
                              );
                              else
                                return new InkWell( child: new ListView.builder(
                                      itemCount:
                                          names == null ? 0 : names.length,
                                      itemBuilder:
                                          (BuildContext context, int index) {
                                        return new Card( child: new Text(names[index]))
Related