I try to get appointments from Firestore
to display them in datasource in SfCalendar
.
I've tried 2 ways but in both case nothing is displayed.
Here is the code
Event
@JsonSerializable()
class Event {
String uid;
String title;
DateTime from;
DateTime to;
String? comment;
String backgroundColor;
bool isAllDay;
Event({required this.uid, required this.title, required this.from,
required this.to, this.comment, required this.backgroundColor, this.isAllDay = false});
factory Event.fromJson(Map<String, dynamic> json) => _$EventFromJson(json);
Map<String, dynamic> toJson() => _$EventToJson(this);
}
EventDataSource
class EventDataSource extends CalendarDataSource {
EventDataSource(List<Event> appointments) {
this.appointments = appointments;
}
Event getEvent(int index) => appointments![index] as Event;
@override
DateTime getStartTime(int index) => getEvent(index).from;
@override
DateTime getEndTime(int index) => getEvent(index).to;
@override
String getSubject(int index) => getEvent(index).title;
@override
Color getColor(int index) => Utils.getColorFromString(getEvent(index).backgroundColor);
@override
bool isAllDay(int index) => getEvent(index).isAllDay;
}
EventViewModel
class EventViewModel extends ChangeNotifier {
final FirebaseFirestore _db = FirebaseFirestore.instance;
final List<Event> _events = [];
DateTime _selectedDate = DateTime.now();
List<Event> get events => _events;
List<Event> get eventsOfSelectedDate => _events;
DateTime get selectedDate => _selectedDate;
void setDate(DateTime date) => _selectedDate = date;
Future createInstructorEvent(Event event) async {
final eventDocument = _db.collection("instructorsEvent")
.doc();
final json = event.toJson();
await eventDocument.set(json);
}
}
CalendarWidget
class CalendarWidget extends StatefulWidget {
const CalendarWidget({Key? key}) : super(key: key);
@override
State<CalendarWidget> createState() => _CalendarWidgetState();
}
class _CalendarWidgetState extends State<CalendarWidget> {
@override
Widget build(BuildContext context) {
//final events = Provider.of<EventViewModel>(context).events;
return Scaffold(
body: SfCalendar(
//dataSource: EventDataSource(events),
view: CalendarView.month,
onLongPress: (details) {
final eventViewModel = Provider.of<EventViewModel>(context, listen: false);
eventViewModel.setDate(details.date!);
showModalBottomSheet(
context: context,
builder: (context) => const DailyWidget(),
);
},
),
floatingActionButton: FloatingActionButton(
child: const Icon(
Icons.add,
color: white,
),
onPressed: () {
_clickOnFAB(context);
},
),
);
}
void _clickOnFAB(BuildContext context) {
Utils.goToEventPlanningScreen(context);
}
}
Try #1
I've tried what's explained in SfCalendar documentation but it doesn't work.
CalendarWidget
class CalendarWidget extends StatefulWidget {
const CalendarWidget({Key? key}) : super(key: key);
@override
State<CalendarWidget> createState() => _CalendarWidgetState();
}
class _CalendarWidgetState extends State<CalendarWidget> {
EventDataSource? events; //--------------------------------------- TODO 1
final FirebaseFirestore _db = FirebaseFirestore.instance; //--------------------------------------- TODO 2
@override
void initState() {
getInstructorEvent().then((results) {
SchedulerBinding.instance.addPostFrameCallback((timeStamp) { //------------------------- TODO 3
setState(() {});
});
});
super.initState();
}
@override
Widget build(BuildContext context) {
//final events = Provider.of<EventViewModel>(context).events;
return Scaffold(
body: SfCalendar(
dataSource: events, //--------------------------------------- TODO 5
//dataSource: EventDataSource(events),
view: CalendarView.month,
onLongPress: (details) {
final eventViewModel = Provider.of<EventViewModel>(context, listen: false);
eventViewModel.setDate(details.date!);
showModalBottomSheet(
context: context,
builder: (context) => const DailyWidget(),
);
},
),
floatingActionButton: FloatingActionButton(
child: const Icon(
Icons.add,
color: white,
),
onPressed: () {
_clickOnFAB(context);
},
),
);
}
void _clickOnFAB(BuildContext context) {
Utils.goToEventPlanningScreen(context);
}
Future getInstructorEvent() async { //--------------------------------------- TODO 4
var snapshot = await _db.collection(instructorsEvent)
.get();
List<Event> eventList = snapshot.docs.map(
(e) => Event(
uid: e.data()["uid"],
title: e.data()["title"],
from: DateFormat('dd/MM/yyyy HH:mm:ss').parse(e.data()['from']),
to: DateFormat('dd/MM/yyyy HH:mm:ss').parse(e.data()['yo']),
comment: e.data()["comment"],
backgroundColor: e.data()["backgroundColor"],
isAllDay: e.data()["isAllDay"],
)
).toList();
setState(() {
events = EventDataSource(eventList);
print("EventDataSource 1: $events");
});
}
}
Try #2
EventViewModel
class EventViewModel extends ChangeNotifier {
final FirebaseFirestore _db = FirebaseFirestore.instance;
List<Event> _events = [];
DateTime _selectedDate = DateTime.now();
List<Event> get events => _events;
List<Event> get eventsOfSelectedDate => _events;
DateTime get selectedDate => _selectedDate;
void setDate(DateTime date) => _selectedDate = date;
Future createInstructorEvent(Event event) async {
final eventDocument = _db.collection("instructorsEvent")
.doc();
final json = event.toJson();
await eventDocument.set(json);
}
Future getInstructorEvent() async {
var snapshot = await _db.collection(instructorsEvent)
.get();
List<Event> list = snapshot.docs
.map((e) => Event(
uid: e.data()["uid"],
title: e.data()["title"],
from: DateFormat("dd/MM/yyyy HH:mm:ss").parse(e.data()["from"]),
to: DateFormat("dd/MM/yyyy HH:mm:ss").parse(e.data()["to"]),
comment: e.data()["comment"],
backgroundColor: e.data()["backgroundColor"],
isAllDay: e.data()["isAllDay"],
))
.toList();
}
}
CalendarWidget
class _CalendarWidgetState extends State<CalendarWidget> {
Future<dynamic>? futureEvents; //--------------------------------------- TODO 1
@override
void initState() {
futureEvents = _getInstructorEvent(); //--------------------------------------- TODO 2
super.initState();
}
@override
Widget build(BuildContext context) {
//final events = Provider.of<EventViewModel>(context).events;
return Scaffold(
body: sfCalendarMonth(), //--------------------------------------- TODO 5
floatingActionButton: FloatingActionButton(
child: const Icon(
Icons.add,
color: white,
),
onPressed: () {
_clickOnFAB(context);
},
),
);
}
void _clickOnFAB(BuildContext context) {
Utils.goToEventPlanningScreen(context);
}
_getInstructorEvent() async {
final eventListTest = Provider.of<EventViewModel>(context, listen: false); //----------------- TODO 3
eventListTest.getInstructorEvent();
}
Widget sfCalendarMonth() => FutureBuilder(
future: futureEvents,
builder: (context, AsyncSnapshot snapshot) {
if(snapshot.hasData) {
return SfCalendar(
dataSource: snapshot.data, //--------------------------------------- TODO 4
view: CalendarView.month,
onLongPress: (details) {
final eventViewModel = Provider.of<EventViewModel>(context, listen: false);
eventViewModel.setDate(details.date!);
showModalBottomSheet(
context: context,
builder: (context) => const DailyWidget(),
);
},
);
}
return Container();
},
);
}
Try #3
EventViewModel
class EventViewModel extends ChangeNotifier {
final FirebaseFirestore _db = FirebaseFirestore.instance;
final List<Event> _events = [];
DateTime _selectedDate = DateTime.now();
Future<dynamic> getInstructorEvent() async {
var snapshot = await _db.collection(instructorsEvent)
.get();
List<Event> list = snapshot.docs
.map((e) => Event(
uid: e.data()["uid"],
title: e.data()["title"],
from: DateFormat("dd-MM-yyyyTHH:mm:ss").parse(e.data()["from"]),
to: DateFormat("dd-MM-yyyyTHH:mm:ss").parse(e.data()["to"]),
comment: e.data()["comment"],
backgroundColor: e.data()["backgroundColor"],
isAllDay: e.data()["isAllDay"],
))
.toList();
print("Appointments in VM: $list"); //------ return [Instance of 'Event']
}
}
CalendarWidget
class CalendarWidget extends StatefulWidget {
const CalendarWidget({Key? key}) : super(key: key);
@override
State<CalendarWidget> createState() => _CalendarWidgetState();
}
class _CalendarWidgetState extends State<CalendarWidget> {
Future<dynamic>? _futureEvents; //---------------------------- TODO 1
@override
void initState() { //---------------------------- TODO 2
_futureEvents = _getInstructorEvent();
print("Appointments in initState 0: $_futureEvents"); //--- return Instance of 'Future<dynamic>' 'Future<dynamic>'
super.initState();
}
@override
Widget build(BuildContext context) {
final events = Provider.of<EventViewModel>(context).events;
return Scaffold(
body: sfCalendarMonth(),
floatingActionButton: FloatingActionButton(
child: const Icon(
Icons.add,
color: white,
),
onPressed: () {
_clickOnFAB(context);
},
),
);
}
//****************************************************************************
// Click on FAB
//****************************************************************************
void _clickOnFAB(BuildContext context) {
Utils.goToEventPlanningScreen(context);
}
Future<dynamic> _getInstructorEvent() async {
final eventListTest = Provider.of<EventViewModel>(context, listen: false);
dynamic eventList = await eventListTest.getInstructorEvent();
return eventList; //---------------------------- TODO 3
}
Widget sfCalendarMonth() => FutureBuilder(
future: _futureEvents, //---------------------------- TODO 4
builder: (context, AsyncSnapshot<dynamic> snapshot) {
final event = snapshot.data;
print("Appointments in FutureBuilder 1: $event"); //-- return null
if(snapshot.hasData) {
return SfCalendar(
dataSource: snapshot.data,
view: CalendarView.month,
onLongPress: (details) {
final eventViewModel = Provider.of<EventViewModel>(context, listen: false);
eventViewModel.setDate(details.date!);
showModalBottomSheet(
context: context,
builder: (context) => const DailyWidget(),
);
},
);
}
return const Center(
child: Text(
"Nothing to show",
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
),
),
);
},
);
}
Thanks in advance