Search code examples
flutterprovider

I have to go to this screen twice to load data from fetchAndSet in flutter


When I visited the page first time, it just shows circularProgressIndicator. After going back when I visit that page second time, then circularProgressIndicator shows up and other listview.builder appears perfectly. I have updated the code in question. Any kind of help is much appreciated.

FutureBuilder(
  future: Provider.of<AppointmentsProvider>(context, listen: false)
      .fetchAndSetAvailableSlots(),
  builder: (ctx, snapShot) => Column(
    children: [
      Container(
        margin: EdgeInsets.all(5),
        decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(10),
          color: Colors.blue,
        ),
        child: SizedBox(
          height: 380,
          child: snapShot.connectionState == ConnectionState.waiting
              ? Center(
                  child: CircularProgressIndicator(
                    color: Colors.white,
                  ),
                )
              : ListView.builder(
                  itemCount: list.length,
                  itemBuilder: (ctx, i) => Card(
                    elevation: 5,
                    margin: EdgeInsets.all(10),
                    shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(10.0)),
                    child: CheckboxListTile(
                      secondary: Icon(
                        Icons.alarm,
                      ),
                      activeColor: Colors.green,
                      // checkColor: Colors.black,
                      selectedTileColor: Colors.blue,
                      // tileColor: Colors.greenAccent,
                      title: Text(list[i].time),
                      value: list[i].isSelected,
                      onChanged: (value) {
                        onCheckChanged(list[i], list, value);
                      },
                    ),
                  ),
                ),
        ),
      ),
      ElevatedButton.icon(
        onPressed: () async {
          await Firebase.initializeApp();
          FirebaseFirestore.instance.collection('appointments').add({
            'id': DateTime.now().toString(),
            'date': widget.formatDate,
            'description': 'description etc.',
            'type': 'type etc.',
            'uid': 'uid etc.',
            'timeSlot': timeSlot,
          });
        },
        icon: Icon(Icons.arrow_forward),
        label: Text('Add Now!'),
      ),
    ],
  ),
);

---here is the fetchAndSet function---

Future<void> fetchAndSetAvailableSlots() async {
await Firebase.initializeApp();
QuerySnapshot<Map<String, dynamic>> data = await FirebaseFirestore.instance
    .collection('appointments')
    .where('date', isEqualTo: 'Dec 11, 2021')
    .get();
List<TimeSlot> bookedSlots = [];

data.docs.forEach(
  (element) async {
     FirebaseFirestore.instance.collection('Questions').doc(userId).get();
    DocumentSnapshot<Map<String, dynamic>> item = await FirebaseFirestore
        .instance
        .collection('appointments')
        .doc('${element.id}')
        .get();

    bookedSlots
        .add(TimeSlot(isSelected: false, time: item.data()['timeSlot']));
  },
);
availableTimeSlots = bookedSlots;
print(bookedSlots);
notifyListeners();

}


Solution

  • first of all I would suggest moving

    Firebase.initializeApp();

    Into your runApp function.

    Regarding your second problem it looks like you are using Provider. If so I would suggest passing an bool loading determining wether or not await getting data is still running. Also a Futurebuilder/Streambuilder could be helpful in displaying that data. Your problem sounds like the widget doesnt rebuild if data is fetched