Search code examples
firebaseflutterdartflutter-futurebuilderflutter-future

FutureBuilder does not complete when using an Anmiation inside


I have a FutureBuilder, where I retrieve data from Firestore. I do that in initState, as it was often suggested here.

Future<Tour> _tour;

  @override
  void initState() {
    super.initState();
    _tour = _tourService.getTourDataPerEmployee(employeeID: userinfo.user.uid);
  }

My FutureBuilder looks like this:

FutureBuilder(
        future: _tour,
        builder: (context, snapshot) {
          if (snapshot.hasData) {
            print(snapshot.data.waypoints);
            return Container(
                child: ListView.builder(
              itemCount: snapshot.data.waypoints.length,
              itemBuilder: (context, index) {
                return TimelineTile(
                  nodePosition: 0.03,
                  contents: TourTile(
                    tour: snapshot.data,
                    index: index,
                  ),
                  node: TimelineNode(
                    indicator: CustomIndicator(
                        finished: snapshot.data.waypoints[index].finished),
                    startConnector: CustomConnector(
                        finished: snapshot.data.waypoints[index].finished,
                        inProgress: false),
                    endConnector: CustomConnector(
                        finished: snapshot.data.waypoints[index].finished,
                        inProgress: index >= snapshot.data.waypoints.length - 1
                            ? true
                            : snapshot.data.waypoints[index + 1].finished
                                ? false
                                : true),
                  ),
                );
              },
            ));
          } else {
            return Center(child: Text("Please wait"));
          }
        },
      ),

This is how I tried to add the animation:

CircularProgressIndicator()

This works fine, when I however try to replace the simple Text("Please wait") with an animation, I get weird results. I could get no result from the future at all, sometimes there are only a few results. The data simply does not seem to arrive sometimes, because the snapshot.data does print null sometimes, sometimes all results are there. I cannot see any coherences between the animation and the builder.


Solution

  • Try this:

    Future<Tour> _tour;
      
      getTours() async {
        return await _tourService.getTourDataPerEmployee(employeeID: userinfo.user.uid);
    
      }
    
      @override
      void initState() {
        super.initState();
        _tour = getTours();
      }
    

    Then in Widget:

    FutureBuilder(
            future: _tour,
            builder: (context, snapshot) {
              if (snapshot.hasData) {
                print(snapshot.data.waypoints);
                return Container(
                    child: ListView.builder(
                  itemCount: snapshot.data.waypoints.length,
                  itemBuilder: (context, index) {
                    return TimelineTile(
                      nodePosition: 0.03,
                      contents: TourTile(
                        tour: snapshot.data,
                        index: index,
                      ),
                      node: TimelineNode(
                        indicator: CustomIndicator(
                            finished: snapshot.data.waypoints[index].finished),
                        startConnector: CustomConnector(
                            finished: snapshot.data.waypoints[index].finished,
                            inProgress: false),
                        endConnector: CustomConnector(
                            finished: snapshot.data.waypoints[index].finished,
                            inProgress: index >= snapshot.data.waypoints.length - 1
                                ? true
                                : snapshot.data.waypoints[index + 1].finished
                                    ? false
                                    : true),
                      ),
                    );
                  },
                ));
              } else {
                return CircularProgressIndicator();
              }
            },
          ),
    

    you can even call getTours() in future

    FutureBuilder(
            future: getTours(),