How to convert Future<int> to int?

0

So I'm trying to display a pie chart using the fl_chart plugin. The data for the chart is being retrieved from firestore. I have this function that is used to display the data:

List<PieChartSectionData> showSection(AsyncSnapshot<QuerySnapshot> snapshot) {
    return List.generate(length, (i) {
      final isTouched = i == touchedIndex;
      final double fontSize = isTouched ? 25 : 16;
      final double radius = isTouched ? 60 : 50;
      return PieChartSectionData(
        color: Color(int.parse(cerealData[i].colorVal)),
        value: cerealData[i].rating,
        title: cerealData[i].rating.toString(),
        radius: radius,
        titleStyle: TextStyle(
            fontSize: fontSize,
            fontWeight: FontWeight.bold,
            color: const Color(0xffffffff)),
      );
    });
  }

The List.generate() takes an int as an argument. Since I'm displaying realtime data, I'm trying to get the number of documents present in my collection. For that, I have a function called getLength():

  void getLength(AsyncSnapshot<QuerySnapshot> snapshot) async {
    length = await Firestore.instance.collection('cereal').snapshots().length;
    cerealData =
        snapshot.data.documents.map((e) => Cereal.fromJson(e.data)).toList();
  }

However, when I run the code, I get:

 Another exception was thrown: type 'Future<int>' is not a subtype of type 'int'

The entire code:

class _FlChartPageState extends State<FlChartPage> {
  int touchedIndex;
  var length;
  List<Cereal> cerealData;

  void getLength(AsyncSnapshot<QuerySnapshot> snapshot) async {
    length = await Firestore.instance.collection('cereal').snapshots().length;
    cerealData =
        snapshot.data.documents.map((e) => Cereal.fromJson(e.data)).toList();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: StreamBuilder<QuerySnapshot>(
          stream: Firestore.instance.collection('cereal').snapshots(),
          builder: (context, snapshot) {
            getLength(snapshot);
            if (!snapshot.hasData)
              return CircularProgressIndicator();
            else {
              return PieChart(PieChartData(
                  pieTouchData: PieTouchData(touchCallback: (pieTouchResponse) {
                    setState(() {
                      if (pieTouchResponse.touchInput is FlLongPressEnd ||
                          pieTouchResponse.touchInput is FlPanEnd) {
                        touchedIndex = -1;
                      } else {
                        touchedIndex = pieTouchResponse.touchedSectionIndex;
                      }
                    });
                  }),
                  borderData: FlBorderData(show: false),
                  sectionsSpace: 0,
                  centerSpaceRadius: 40,
                  sections: showSection(snapshot)));
            }
          }),
    );
  }

  List<PieChartSectionData> showSection(AsyncSnapshot<QuerySnapshot> snapshot) {
    return List.generate(length, (i) {
      final isTouched = i == touchedIndex;
      final double fontSize = isTouched ? 25 : 16;
      final double radius = isTouched ? 60 : 50;
      return PieChartSectionData(
        color: Color(int.parse(cerealData[i].colorVal)),
        value: cerealData[i].rating,
        title: cerealData[i].rating.toString(),
        radius: radius,
        titleStyle: TextStyle(
            fontSize: fontSize,
            fontWeight: FontWeight.bold,
            color: const Color(0xffffffff)),
      );
    });
  }
}

I read somewhere that awaiting the future gets rid of the Future. But that doesn't work here. How do I fix this?

Edit: It works if I simply pass the number of documents instead of length in List.generate(). But this won't work if there are changes to the collection. So how do I convert Future to int?

asynchronous
flutter
google-cloud-firestore
async-await
future
asked on Stack Overflow Apr 5, 2020 by U. Watt • edited Apr 5, 2020 by U. Watt

2 Answers

1

I think you aren't getting the length of the documents, you are getting the length of the snapshots if you want to get the documents length :

QuerySnapshot querySnapshot = await Firestore.instance.collection('cereal').getDocuments();
    int length = querySnapshot.documents.length;

answered on Stack Overflow Apr 5, 2020 by Henok • edited Apr 5, 2020 by Henok
1

In get getLength function you are trying to get length which is actually async task which returns future and because of that you are getting following error.

Change your method with following metod

getLength()async{
 Firestore.instance.collection('cereal').snapshots().length.then((len){
  length = len;
  cerealData =
        snapshot.data.documents.map((e) => Cereal.fromJson(e.data)).toList(); 
  });
}
answered on Stack Overflow Apr 5, 2020 by Viren V Varasadiya

User contributions licensed under CC BY-SA 3.0