Ad

Initialising Variable In InitState

I'm initialising a variable in initState(){}:

@override
  void initState() {
    getDataFromFirestore();
    super.initState();

    });
  }

The method is asyn and basically gets data from Firestore to populate an object '_markerMap' with data. This property is then used as a property in a widget. And this widget is called in my build method.

Widget build(BuildContext context) {
    return new Scaffold(
      body: MyWidget(
            markerMap: _markerMap)
     );
  ....
 }

MyWidget is a calendar. markerMaps adds icons to certain dates on the calendar. The markers are only sometimes added to the calendar. So the failure is intermittent. Is is safe to assume that in initState() the data will load from firestore to initialise the variable from Firestore. Any thoughts what might be happening and why only sometimes the markers show up on the calendar?

adding code where _markerMap is set

getDataFromFirestore() async {
    await FirebaseAuth.instance.currentUser().then((user) {
      Firestore.instance.collection('availableDates').where('bandId', isEqualTo: user.uid).snapshots().listen(
              (data) => data.documents.forEach((doc) => _markerMap.add(
              doc['availableDates'].toDate(),
              Event(
                  date:doc['availableDates'].toDate(),
                  title: 'hello',
                  icon: _presentIcon(doc['availableDates'].toDate().day.toString())))));
      setState(() {});
    }).catchError((onError){
    });
  }
Ad

Answer

As I can see from your getDataFromFirestore method, you perform the widget rebuild (setState call) right after you get the User object (FirebaseAuth.instance.currentUser() call).

However, you modify _markerMap variable later on - only when your Firestore.instance.collection query is complete. In this case setState call where it is right now is redundant.

Calling setState inside of your listen callback should solve the problem.

e.g.

final _markerMap = {};

getDataFromFirestore() async {
  await FirebaseAuth.instance.currentUser().then((user) {
    Firestore.instance
      .collection('availableDates')
      .where('bandId', isEqualTo: user.uid)
      .snapshots()
      .listen((data) => data.documents.forEach((doc) {
        setState(() { // Here is the setState call
          _markerMap.add(
            doc['availableDates'].toDate(),
            Event(
              date: doc['availableDates'].toDate(),
              title: 'hello',
              icon: _presentIcon(doc['availableDates'].toDate().day.toString())
            )
          );
        });
      }));
  }).catchError((onError) {});
}

Please double check this example code. My general advice is correct, however I did not test this on my end.

Ad
source: stackoverflow.com
Ad