title: How to get all events in a month using table_calendar in flutter?
body: <p>I have built a calendar with user's appointments using table_calendar in flutter. In my current code, I can only return all appointments of the user. Now, I am trying to fetch all appointments within a same month only and display them below the calendar. That is to say, when I swap the month on the calendar, I should  <strong>only</strong> see a list of appointments within the month I am currently looking at.</p>
  <p>Currently, I am fetching all appointment records of the user from backend. To achieve my goal, which way will be easier:</p>
  <p><em>by defining the 'change month button' with date info of the first day of that month and using it to select corresponding data in backend</em></p>
  <p><strong>OR</strong></p>
  <p><em>still retrieving all appointment records and filter them in frontend somehow?</em></p>
  <p>Can anyone please help me achieving my goal with specific solution?</p>
  <p>(As shown in my current output below, while I am at October, I am still seeing the appointment in June).
  <a href="https://i.stack.imgur.com/rb7i0.jpg" rel="nofollow noreferrer">Current Output</a></p>
  <p><strong>Frontend code:</strong></p>
  <pre><code>import 'package:flutter/material.dart';
  import 'package:table_calendar/table_calendar.dart';
  import 'package:frontend/util/authentication.dart';
  import 'package:frontend/util/serverDetails.dart';
  import 'package:http/http.dart' as http;
  import 'package:frontend/components/appointment.dart';
  import 'package:frontend/screens/appointmentdetail.dart';
  import 'dart:convert';
  import 'package:intl/intl.dart';
  import 'package:frontend/main.dart';
  import 'package:frontend/screens/appointmentlist.dart';
  
  class Appointments extends StatefulWidget {
    @override
    _AppointmentsState createState() =&gt; _AppointmentsState();
  }
  
  class _AppointmentsState extends State&lt;Appointments&gt;
      with TickerProviderStateMixin {
    var _calendarController;
    Map&lt;DateTime, List&gt; _events;
    List&lt;Appointment&gt; _samemonthevents = List&lt;Appointment&gt;();
    AnimationController _animationController;
  
    @override
    void initState() {
      super.initState();
      _events = Map&lt;DateTime, List&gt;();
      _calendarController = CalendarController();
  
      getSameMonthAppointments();
      _animationController = AnimationController(
        vsync: this,
        duration: const Duration(milliseconds: 400),
      );
      _animationController.forward();
    }
  
    @override
    void dispose() {
      _calendarController.dispose();
      super.dispose();
    }
  
    getSameMonthAppointments() async {
      String currentToken = await Authentication.getCurrentToken();
      print(currentToken);
      if (currentToken == null) {
        print('bouncing');
        Authentication.bounceUser(context);
      } else {
        String auth = &quot;Bearer &quot; + currentToken;
        String url = ServerDetails.ip +
            ':' +
            ServerDetails.port +
            ServerDetails.api +
            'me/appointments';
        print(url);
        Map&lt;String, String&gt; headers = {&quot;Authorization&quot;: auth};
        print(headers);
        var jsonResponse = null;
        var response = await http.get(url, headers: headers);
        print(response.body);
        if (response.statusCode == 200) {
          print(&quot;200&quot; + response.body);
          jsonResponse = json.decode(response.body);
          if (jsonResponse != null) {
            setState(() {
              for (var doc in jsonResponse) {
                _samemonthevents.add(Appointment.fromJson(doc));
              }
            });
          }
        } else {
          print(response.body);
        }
      }
    }
  
    void _onVisibleDaysChanged(
        DateTime first, DateTime last, CalendarFormat format) {
      print('CALLBACK: _onVisibleDaysChanged');
    }
  
    @override
    Widget build(BuildContext context) {
      return Scaffold(
          appBar: PreferredSize(
            preferredSize: Size.fromHeight(60.0),
            child: AppBar(
              leading: new IconButton(
                  icon: new Icon(Icons.arrow_back),
                  color: Colors.black,
                  onPressed: () {
                    setState(() {});
                    Navigator.push(context,
                        MaterialPageRoute(builder: (context) =&gt; MainPage()));
                  }),
              centerTitle: true,
              title: Text(&quot;Appointment&quot;, style: TextStyle(color: Colors.black)),
              backgroundColor: Colors.white,
              brightness: Brightness.light,
              automaticallyImplyLeading: false,
  //          backgroundColor: Color(0x44000000),
              elevation: 0.5,
              actions: &lt;Widget&gt;[
                IconButton(
                  color: Colors.black,
                  icon: Icon(Icons.list),
                  onPressed: () {
                    setState(() {});
                    Navigator.push(
                        context,
                        MaterialPageRoute(
                            builder: (context) =&gt; AppointmentList()));
                  },
                )
              ],
            ),
          ),
          body: new Builder(builder: (BuildContext context) {
            return new Column(children: &lt;Widget&gt;[
              _buildTableCalendarWithBuilders(),
              const SizedBox(height: 8.0),
              const SizedBox(height: 8.0),
              //_buildEventList()
              //_buildsameMonthEventList()
              Expanded(child: _buildsameMonthEventList()),
            ]);
          }));
    }
  
    // More advanced TableCalendar configuration (using Builders &amp; Styles)
    Widget _buildTableCalendarWithBuilders() {
      return TableCalendar(
        calendarController: _calendarController,
        events: _events,
        //holidays: _holidays,
        initialCalendarFormat: CalendarFormat.month,
        formatAnimation: FormatAnimation.slide,
        startingDayOfWeek: StartingDayOfWeek.sunday,
        availableGestures: AvailableGestures.all,
        availableCalendarFormats: const {CalendarFormat.month: ''},
        calendarStyle: CalendarStyle(
          outsideDaysVisible: false,
          weekendStyle: TextStyle().copyWith(color: Colors.blue[800]),
          holidayStyle: TextStyle().copyWith(color: Colors.blue[800]),
        ),
        daysOfWeekStyle: DaysOfWeekStyle(
          weekendStyle: TextStyle().copyWith(color: Colors.blue[600]),
        ),
        headerStyle: HeaderStyle(
          centerHeaderTitle: true,
          formatButtonVisible: false,
        ),
        builders: CalendarBuilders(
          selectedDayBuilder: (context, date, _) {
            return FadeTransition(
              opacity: Tween(begin: 0.0, end: 1.0).animate(_animationController),
              child: Container(
                margin: const EdgeInsets.all(4.0),
                alignment: Alignment.center,
                decoration: BoxDecoration(
                    color: Colors.blue[300],
                    borderRadius: BorderRadius.circular(36.0),
                    border: Border.all(width: 2, color: Colors.blue[300])),
                child: Text(
                  '${date.day}',
                  style: TextStyle().copyWith(
                      fontSize: 20.0,
                      color: Colors.black,
                      fontWeight: FontWeight.bold),
                ),
              ),
            );
          },
          todayDayBuilder: (context, date, _) {
            return Container(
              margin: const EdgeInsets.all(4.0),
              alignment: Alignment.center,
              decoration: BoxDecoration(
                  color: Colors.white,
                  borderRadius: BorderRadius.circular(36.0),
                  border: Border.all(width: 2, color: Colors.white)),
              child: Text(
                '${date.day}',
                style: TextStyle().copyWith(
                    fontSize: 20.0,
                    color: Colors.black,
                    fontWeight: FontWeight.bold),
              ),
            );
          },
          markersBuilder: (context, date, events, holidays) {
            final children = &lt;Widget&gt;[];
  
            if (events.isNotEmpty) {
              children.add(
                Positioned(
                  child: _buildEventsMarker(date, events),
                ),
              );
            }
  
            if (holidays.isNotEmpty) {
              children.add(
                Positioned(
                  right: -2,
                  top: -2,
                  child: _buildHolidaysMarker(),
                ),
              );
            }
  
            return children;
          },
        ),
        onVisibleDaysChanged: _onVisibleDaysChanged,
      );
    }
  
    Widget _buildEventsMarker(DateTime date, List events) {
      return AnimatedContainer(
        duration: const Duration(milliseconds: 300),
        margin: const EdgeInsets.all(4.0),
        alignment: Alignment.center,
        decoration: BoxDecoration(
            borderRadius: BorderRadius.circular(36.0),
            border: Border.all(width: 2, color: Colors.blue[300])),
      );
    }
  
    Widget _buildHolidaysMarker() {
      return Icon(
        Icons.add_box,
        size: 20.0,
        color: Colors.blueGrey[800],
      );
    }
  
    Widget _buildsameMonthEventList() {
      return Scaffold(
          appBar: PreferredSize(
            preferredSize: Size.fromHeight(22.0),
            child: AppBar(
              centerTitle: true,
              title: Text(&quot;Appointments of Current Month&quot;,
                  style: TextStyle(color: Colors.black, fontSize: 18)),
              backgroundColor: Colors.yellow[200],
              brightness: Brightness.light,
              automaticallyImplyLeading: false,
  //          backgroundColor: Color(0x44000000),
              elevation: 0.5,
            ),
          ),
          body: (_samemonthevents.length == 0)
              ? Text(&quot;No appointment record in current month!&quot;,
                  textAlign: TextAlign.center,
                  style: TextStyle(color: Colors.black, fontSize: 16))
              : ListView(
                  children: _samemonthevents
                      .map((event) =&gt; Container(
                          decoration: BoxDecoration(
                            border: Border.all(width: 0.8),
                            borderRadius: BorderRadius.circular(12.0),
                          ),
                          margin: const EdgeInsets.symmetric(
                              horizontal: 8.0, vertical: 4.0),
                          child: (event is Appointment)
                              ? ListTile(
                                  leading: Column(children: &lt;Widget&gt;[
                                    //Show Weekday, Month and day of Appiontment
                                    Text(
                                        DateFormat('EE').format(event.date) +
                                            '  ' +
                                            DateFormat.MMMd().format(event.date),
                                        style: TextStyle(
                                          color: Colors.blue.withOpacity(1.0),
                                          fontWeight: FontWeight.bold,
                                        )),
                                    //Show Start Time of Appointment
                                    Text(DateFormat.jm().format(event.date),
                                        textAlign: TextAlign.center,
                                        overflow: TextOverflow.ellipsis,
                                        style: TextStyle(
                                          fontWeight: FontWeight.bold,
                                          height: 1.5,
                                        )),
                                    //Show End Time of Appointment
                                    Text(
                                      DateFormat.jm().format(event.date.add(
                                          Duration(
                                              minutes: event.duration ?? 0))),
                                      style: TextStyle(
                                          color: Colors.black.withOpacity(0.6)),
                                    ),
                                  ]), //Text(DateFormat.Hm().format(event.date)),//DateFormat.Hm().format(now)
                                  title: Text(event.title),
                                  trailing: event.status == 'UNCONFIRMED'
                                      ? Column(children: &lt;Widget&gt;[
                                          //event.status=='CONFIRMED' ?
                                          Icon(Icons.error,
                                              color: Colors.pink,
                                              //size:25.0,
                                              semanticLabel:
                                                  'Unconfirmed Appointment'), //:Container(width:0,height:0),
                                          Icon(Icons.arrow_right),
                                        ])
                                      : Icon(Icons.arrow_right),
                                  onTap: () {
                                    setState(() {});
                                    Navigator.push(
                                        context,
                                        MaterialPageRoute(
                                            builder: (context) =&gt;
                                                AppointmentDetail(event)));
                                  },
                                )
                              : null))
                      .toList()));
    }
  }
  </code></pre>
  <p><strong>Backend Code:</strong></p>
  <p>AppointmentAPI.java</p>
  <pre><code>    @GET
      @Path(&quot;me/appointments&quot;)
      @Secured(UserRole.PATIENT)
      @JSONP(queryParam = &quot;callback&quot;)
      @Produces(MediaType.APPLICATION_JSON)
      public Response listMyAppointments(
              @Context SecurityContext sc,
              @QueryParam(&quot;since&quot;) String since,
              @QueryParam(&quot;until&quot;) String until,
              @QueryParam(&quot;is_confirmed&quot;) Boolean is_confirmed) {
  
          String uid = sc.getUserPrincipal().getName();
          List&lt;Appointment&gt; results = retrieveUserAppointments(uid, since, until, is_confirmed);
  
          return Response.ok(results).build();
      }
  </code></pre>
  <p>AppointmentMapper.java</p>
  <pre><code>    List&lt;Appointment&gt; getAppointmentsByUserId(
              @Param(&quot;uid&quot;)  String uid,
              @Param(&quot;since&quot;)  String since,
              @Param(&quot;until&quot;)  String until,
              @Param(&quot;status&quot;) AppointmentStatus status);
  </code></pre>
  <p>AppointmentMapper.xml</p>
  <pre><code>&lt;mapper namespace=&quot;com.sec.db.AppointmentMapper&quot;&gt;
      &lt;select id=&quot;getAppointmentById&quot; parameterType=&quot;String&quot; resultType=&quot;com.sec.entity.Appointment&quot;&gt;
          SELECT * FROM Appointment WHERE id= #{id}
      &lt;/select&gt;
  
      &lt;select id=&quot;getAppointmentsByUserId&quot; resultType=&quot;com.sec.entity.Appointment&quot;&gt;
          SELECT *
          FROM Appointment
          WHERE uid= #{uid}
          &lt;choose&gt;
              &lt;when test=&quot;since != null and until != null&quot;&gt;
                  AND date BETWEEN #{since} AND #{until}
              &lt;/when&gt;
              &lt;when test=&quot;since != null and until == null&quot;&gt;
                  AND date &gt; #{since}
              &lt;/when&gt;
              &lt;when test=&quot;since == null and until != null&quot;&gt;
                  &lt;![CDATA[
                  AND date &lt; #{until}
                  ]]&gt;
              &lt;/when&gt;
          &lt;/choose&gt;
          &lt;choose&gt;
              &lt;when test=&quot;status == null&quot;&gt;
                  AND status != 'CANCELLED'
              &lt;/when&gt;
              &lt;otherwise&gt;
                  AND status = #{status}
              &lt;/otherwise&gt;
          &lt;/choose&gt;
      &lt;/select&gt;
  </code></pre>
  <p><strong>Json Response Example:</strong></p>
  <pre><code>### Response
  
      Status: 200 OK
  
  ```JSON
  [
    {
      &quot;date&quot;: &quot;2020-06-22T14:15:00Z&quot;,
      &quot;date_change&quot;: &quot;2018-05-14T10:17:40Z&quot;,
      &quot;date_create&quot;: &quot;2018-05-14T10:17:40Z&quot;,
      &quot;detail&quot;: &quot;Inflisaport Insertion&quot;,
      &quot;duration&quot;: 15,
      &quot;id&quot;: &quot;2&quot;,
      &quot;note&quot;: &quot;Looking forward to see you! Take care&quot;,
      &quot;status&quot;: &quot;CONFIRMED&quot;,
      &quot;title&quot;: &quot;Private Hospital&quot;,
      &quot;uid&quot;: &quot;1&quot;
    }
  ]
  </code></pre>