U. Watt
U. Watt

Reputation: 724

How to convert Future<int> to int?

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?

Upvotes: 0

Views: 883

Answers (2)

Henok
Henok

Reputation: 3383

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;

Upvotes: 1

Viren V Varasadiya
Viren V Varasadiya

Reputation: 27147

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(); 
  });
}

Upvotes: 1

Related Questions