Search code examples
flutterdartflutter-layoutflutter-dependenciesdart-pub

Flutter Table Calendar : Showing Event from API to Table Calendar Pub version table_calendar: ^3.0.6


Hi This is my code im new to flutter kindly help me with the when I execute this im getting an error at the value Notifier for the _selectedEvents. im trying to use the API to fetch the data which in the following json format as the package is updated im there is no proper documentation to get events from API and display in the table_calender

API:

{
"payment_status": "1",
"mass_dates": {
    "start_date": "2022-09-05",
    "end_date": "2022-09-17"
},
"church_details": {
    "church_name": "Church"
},
"quote": {
    "quote_id": "3",
    "quote": "And do not forget to do good and to share with others, for with such sacrifices God is pleased.",
    "verse": "Hebrews 13:16"
},
"mass_list": [
    {
        "mass_id": "958",
        "mass_date": "2022-09-05",
        "mass_time": "06:30 am",
        "mass_amount": "120",
        "mass_notes": "Kannada Mass",
        "mass_place": "First Mass",
        "mass_detail": "No Details"
    },
    {
        "mass_id": "959",
        "mass_date": "2022-09-05",
        "mass_time": "06:00 pm",
        "mass_amount": "100",
        "mass_notes": "Kannada Mass",
        "mass_place": "Second Mass",
        "mass_detail": "New mass"
    },
    {
        "mass_id": "960",
        "mass_date": "2022-09-06",
        "mass_time": "06:00 pm",
        "mass_amount": "130",
        "mass_notes": "Kannada Mass",
        "mass_place": "First Mass",
        "mass_detail": "No Details"
    },
    {
        "mass_id": "961",
        "mass_date": "2022-09-07",
        "mass_time": "06:00 pm",
        "mass_amount": "140",
        "mass_notes": "Kannada Mass",
        "mass_place": "First Mass",
        "mass_detail": "No Details"
    },
    {
        "mass_id": "962",
        "mass_date": "2022-09-08",
        "mass_time": "06:30 am",
        "mass_amount": "150",
        "mass_notes": "Kannada Mass",
        "mass_place": "First Mass",
        "mass_detail": "No Details"
    },
    {
        "mass_id": "963",
        "mass_date": "2022-09-09",
        "mass_time": "06:00 pm",
        "mass_amount": "160",
        "mass_notes": "Kannada Mass",
        "mass_place": "First Mass",
        "mass_detail": "No Details"
    },
    {
        "mass_id": "964",
        "mass_date": "2022-09-10",
        "mass_time": "06:30 am",
        "mass_amount": "170",
        "mass_notes": "Kannada Mass",
        "mass_place": "First Mass",
        "mass_detail": "No Details"
    },
    {
        "mass_id": "965",
        "mass_date": "2022-09-10",
        "mass_time": "06:00 pm",
        "mass_amount": "180",
        "mass_notes": "Kannada Mass",
        "mass_place": "Second Mass",
        "mass_detail": "This is Mass is with Sunday Liturgy"
    },
    {
        "mass_id": "966",
        "mass_date": "2022-09-11",
        "mass_time": "07:00 am",
        "mass_amount": "100",
        "mass_notes": "English Mass",
        "mass_place": "First Mass",
        "mass_detail": "This mass is once a week"
    },
    {
        "mass_id": "967",
        "mass_date": "2022-09-11",
        "mass_time": "08:15 am",
        "mass_amount": "110",
        "mass_notes": "Kannada Mass",
        "mass_place": "Second Mass",
        "mass_detail": "This is the Parish main mass"
    },
    {
        "mass_id": "968",
        "mass_date": "2022-09-12",
        "mass_time": "06:30 am",
        "mass_amount": "120",
        "mass_notes": "Kannada Mass",
        "mass_place": "First Mass",
        "mass_detail": "No Details"
    },
    {
        "mass_id": "969",
        "mass_date": "2022-09-12",
        "mass_time": "06:00 pm",
        "mass_amount": "100",
        "mass_notes": "Kannada Mass",
        "mass_place": "Second Mass",
        "mass_detail": "New mass"
    },
    {
        "mass_id": "970",
        "mass_date": "2022-09-13",
        "mass_time": "06:00 pm",
        "mass_amount": "130",
        "mass_notes": "Kannada Mass",
        "mass_place": "First Mass",
        "mass_detail": "No Details"
    },
    {
        "mass_id": "971",
        "mass_date": "2022-09-14",
        "mass_time": "06:00 pm",
        "mass_amount": "140",
        "mass_notes": "Kannada Mass",
        "mass_place": "First Mass",
        "mass_detail": "No Details"
    },
    {
        "mass_id": "972",
        "mass_date": "2022-09-15",
        "mass_time": "06:30 am",
        "mass_amount": "150",
        "mass_notes": "Kannada Mass",
        "mass_place": "First Mass",
        "mass_detail": "No Details"
    },
    {
        "mass_id": "973",
        "mass_date": "2022-09-16",
        "mass_time": "06:00 pm",
        "mass_amount": "160",
        "mass_notes": "Kannada Mass",
        "mass_place": "First Mass",
        "mass_detail": "No Details"
    },
    {
        "mass_id": "974",
        "mass_date": "2022-09-17",
        "mass_time": "06:30 am",
        "mass_amount": "170",
        "mass_notes": "Kannada Mass",
        "mass_place": "First Mass",
        "mass_detail": "No Details"
    },
    {
        "mass_id": "975",
        "mass_date": "2022-09-17",
        "mass_time": "06:00 pm",
        "mass_amount": "180",
        "mass_notes": "Kannada Mass",
        "mass_place": "Second Mass",
        "mass_detail": "This is Mass is with Sunday Liturgy"
    }
]

}

The dart file is as follows:

    import 'dart:collection';
    import 'dart:convert';
    import 'package:flutter/material.dart';
    import 'package:flutter_spinkit/flutter_spinkit.dart';
    import 'package:google_fonts/google_fonts.dart';
    import 'package:mysorediocese/Constants/color_constant.dart';
    import 'package:mysorediocese/Constants/urls.dart';
    import 'package:mysorediocese/models/index.dart';
    import 'package:mysorediocese/pages/cores/UtilsTableCalender.dart';
    import 'package:mysorediocese/pages/widgets/bottom_navigation_travelkuy.dart';
    import 'package:nb_utils/nb_utils.dart';
    import 'package:table_calendar/table_calendar.dart';
    import 'package:http/http.dart' as http;
    
    
    
    class MassIntensionMassListScreen extends StatefulWidget {
      @override
      _MassIntensionMassListScreenState createState() => _MassIntensionMassListScreenState();
    }
    int getHashCode(DateTime key) {
      return key.day * 1000000 + key.month * 10000 + key.year;
    }
    class _MassIntensionMassListScreenState extends State<MassIntensionMassListScreen> with TickerProviderStateMixin{
    
    Masslist_page masslist_page=new Masslist_page();
    
    late String parish_key, uid, msg;
    String fam_head = "Loved";
    String churchname = "Our Church";
    
    late SharedPreferences prefs;
    late bool error, showprogress;
    
      late final ValueNotifier<List<MassListDetatils>> _selectedEvents;
      CalendarFormat _calendarFormat = CalendarFormat.week;
      RangeSelectionMode _rangeSelectionMode = RangeSelectionMode
          .toggledOff; // Can be toggled on/off by longpressing a date
      late DateTime _focusedDay;
      DateTime? _selectedDay;
      DateTime? _rangeStart;
      DateTime? _rangeEnd;
    
      var kEvents;
    
    Future<void> _fetchdata() async {
      prefs = await SharedPreferences.getInstance();
    
      setState(() {
        parish_key = prefs.getString("parish_key") ?? "Loved";
        uid = prefs.getString("uid") ?? "Loved";
        fam_head = prefs.getString("fam_head") ?? "Loved";
      });
    
      String apiurl =
          mMassListPage; //api url
      //dont use http://localhost , because emulator don't get that address
      //insted use your local IP address or use live URL
      //hit "ipconfig" in windows or "ip a" in linux to get you local IP
      try{
        var response = await http.post(Uri.parse(apiurl), body: {
          //get the username text
          'uid':uid,
          'parish_key': parish_key //get password text
        }).whenComplete(() => action());
    
        if (response.statusCode == 200)
        {
          var jsondata1 = json.decode(response.body);
    
          masslist_page = Masslist_page.fromJson(jsondata1);
    
          _focusedDay = DateTime.parse(masslist_page.mass_dates.start_date);
          _selectedDay = _focusedDay;
          _selectedEvents = ValueNotifier(_getEventsForDay(_selectedDay!));
    
          var kEventSource= Map<DateTime, List<MassListDetatils>>.fromIterable(masslist_page.mass_list,key: (element) => DateTime.parse(masslist_page.mass_list[element].mass_time),value: (element) => masslist_page.mass_list);
    
    
    
          kEvents = LinkedHashMap<DateTime, List<MassListDetatils>>(
            equals: isSameDay,
            hashCode: getHashCode,
          )..addAll(kEventSource);
    
    
        } else {
          msg = "No  data Error connecting";
        }
      }catch(e){
    
        print(e);
        // Navigator.of(context)
        //     .pushNamedAndRemoveUntil(mSplashScreenRoute, (Route<dynamic> route) => false);
      }
    
    }
    
    
    
    
    
    
    
    
    
    
    
    
      @override
      void initState() {
        showprogress = true;
        _fetchdata();
        super.initState();
    
    
      }
    
      @override
      void dispose() {
        _selectedEvents.dispose();
        super.dispose();
      }
    
      List<MassListDetatils> _getEventsForDay(DateTime day) {
        // Implementation example
        return kEvents[day] ?? [];
      }
    
    List<DateTime> daysInRange(DateTime first, DateTime last) {
      final dayCount = last.difference(first).inDays + 1;
      return List.generate(
        dayCount,
            (index) => DateTime.utc(first.year, first.month, first.day + index),
      );
    }
      List<MassListDetatils> _getEventsForRange(DateTime start, DateTime end) {
        // Implementation example
        final days = daysInRange(start, end);
    
        return [
          for (final d in days) ..._getEventsForDay(d),
        ];
      }
    
      void _onDaySelected(DateTime selectedDay, DateTime focusedDay) {
        if (!isSameDay(_selectedDay, selectedDay)) {
          setState(() {
            _selectedDay = selectedDay;
            _focusedDay = focusedDay;
            _rangeStart = null; // Important to clean those
            _rangeEnd = null;
            _rangeSelectionMode = RangeSelectionMode.toggledOff;
          });
    
          _selectedEvents.value = _getEventsForDay(selectedDay);
        }
      }
    
      void _onRangeSelected(DateTime? start, DateTime? end, DateTime focusedDay) {
        setState(() {
          _selectedDay = null;
          _focusedDay = focusedDay;
          _rangeStart = start;
          _rangeEnd = end;
          _rangeSelectionMode = RangeSelectionMode.toggledOn;
        });
    
        // `start` or `end` could be null
        if (start != null && end != null) {
          _selectedEvents.value = _getEventsForRange(start, end);
        } else if (start != null) {
          _selectedEvents.value = _getEventsForDay(start);
        } else if (end != null) {
          _selectedEvents.value = _getEventsForDay(end);
        }
      }
    
      @override
      Widget build(BuildContext context) {
        return showprogress
            ? Scaffold(
          body: Container(
              child: Center(child: SpinKitCubeGrid(color: Colors.blue))),
        )
            : Scaffold(
          appBar: AppBar(
            backgroundColor: mBackgroundColor,
            title: Wrap(
              children: [
                Text(
                  masslist_page.church_details.church_name,
                  style: GoogleFonts.dancingScript(
                      textStyle: TextStyle(
                          color: Colors.blue[800],
                          letterSpacing: .5,
                          fontSize: 26,
                          fontWeight: FontWeight.w900)),
                ),
              ],
            ),
            elevation: 1,
          ),
    
          // Setting up Background Color
          backgroundColor: mBackgroundColor,
    
          // Setting up Custom Bottom Navigation Bar
          bottomNavigationBar: BottomNavigationTravelkuy(0),
          body: Column(
            children: [
              TableCalendar<MassListDetatils>(
                firstDay: DateTime.parse(masslist_page.mass_dates.start_date),
                lastDay: DateTime.parse(masslist_page.mass_dates.end_date),
                focusedDay: _focusedDay,
                selectedDayPredicate: (day) => isSameDay(_selectedDay, day),
                rangeStartDay: _rangeStart,
                rangeEndDay: _rangeEnd,
                calendarFormat: _calendarFormat,
                rangeSelectionMode: _rangeSelectionMode,
                eventLoader: _getEventsForDay,
                startingDayOfWeek: StartingDayOfWeek.monday,
                calendarStyle: CalendarStyle(
                  // Use `CalendarStyle` to customize the UI
                  outsideDaysVisible: false,
                ),
                onDaySelected: _onDaySelected,
                onRangeSelected: _onRangeSelected,
                onFormatChanged: (format) {
                  if (_calendarFormat != format) {
                    setState(() {
                      _calendarFormat = format;
                    });
                  }
                },
                onPageChanged: (focusedDay) {
                  _focusedDay = focusedDay;
                },
              ),
              const SizedBox(height: 8.0),
              Expanded(
                child: ValueListenableBuilder<List<MassListDetatils>>(
                  valueListenable: _selectedEvents,
                  builder: (context, value, _) {
                    return ListView.builder(
                      itemCount: value.length,
                      itemBuilder: (context, index) {
                        return Container(
                          margin: const EdgeInsets.symmetric(
                            horizontal: 12.0,
                            vertical: 4.0,
                          ),
                          decoration: BoxDecoration(
                            border: Border.all(),
                            borderRadius: BorderRadius.circular(12.0),
                          ),
                          child: ListTile(
                            onTap: () => print('${value[index].mass_time}'),
                            title: Text('${value[index].mass_id} ${value[index].mass_date} '),
                          ),
                        );
                      },
                    );
                  },
                ),
              ),
            ],
          ),
        );
      }
    action() {
      setState(() {
        showprogress = false;
      });
    }
    }


 looking forward for your kind support

Solution

  • Used

     var mass= masslist_page.mass_list.groupListsBy((element) => DateTime.parse(element.mass_date));
    

    and passed the grouped to

    kEvents = LinkedHashMap<DateTime, List<MassListDetatils>>(
                    equals: isSameDay,
                    hashCode: getHashCode,
                  )..addAll(mass);
    

    this solved to get the data from Api and passing it to the table Calender plugin in flutter. it groups the dates from the API and passes it to the list map and use that list map to pass it in the liked list format specified by the table_calender plugin which fetches the events on a particular date. masslist_page.mass_list is the model created to the resulting json API