Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[syncfusion_flutter_calendar] appointments are shown only after screen touch (iOS) #1869

Open
rmpt opened this issue May 20, 2024 · 5 comments
Labels
calendar Calendar component open Open

Comments

@rmpt
Copy link

rmpt commented May 20, 2024

Bug description

On any view type (month, day, week, etc), appoitments are added to the data source correctly, the notify functions is called but appointments are not shown. Once I touch the screen and do a minimal movement/swipe, all appointments show up.
It means they are there, but now being rendered.

Steps to reproduce

  1. Open - for instance - month view
  2. when onViewChanged gets called, load some appointments asynchronously
  3. noting is shown on the month view
  4. slide the view 1px and everything will be shown

Code sample

Widget code (simplified)
class _MonthViewWidgetState extends State<MonthViewWidget {

   ...

   _reloadEntries(start, end) {
    httpRequest
      .then((entries) {
          dataSource.appointments!.addAll(entries);
          dataSource.notifyListeners(CalendarDataSourceAction.add, entries);
      });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SfCalendar(
          view: CalendarView.month
          dataSource: dataSource,
          onViewChanged: (ViewChangedDetails changeDetails) {
            var start = changeDetails.visibleDates[0];
            var end = changeDetails.visibleDates[changeDetails.visibleDates.length-1];
            _reloadEntries(start, end);
          }
      )
    );
  }
}

Screenshots or Video

appointments.mp4

Stack Traces

n/a

On which target platforms have you observed this bug?

iOS

Flutter Doctor output

Doctor output
[✓] Flutter (Channel stable, 3.22.0, on macOS 14.0 23A344 darwin-arm64, locale pt-PT)
[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
[✓] Xcode - develop for iOS and macOS (Xcode 15.4)
[✗] Chrome - develop for the web (Cannot find Chrome executable at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome)
    ! Cannot find Chrome. Try setting CHROME_EXECUTABLE to a Chrome executable.
[!] Android Studio (not installed)
[✓] IntelliJ IDEA Community Edition (version 2024.1.1)
[✓] VS Code (version 1.89.1)
[✓] Connected device (3 available)
[✓] Network resources
@rmpt
Copy link
Author

rmpt commented May 20, 2024

video added

@VijayakumarMariappan VijayakumarMariappan added calendar Calendar component open Open labels May 21, 2024
@PreethikaSelvam
Copy link
Contributor

Hi @rmpt,

We have analyzed your query and if you're trying to load an appointment when the view changes, we suggest you use the handleLoadMore, which allows you to add the appointments to the data source and notify the listener to update the appointment in the current view. We have shared a UG documentation, KB, and live sample below for your reference.

UG: https://help.syncfusion.com/flutter/calendar/load-more#load-appointments

KB Link: https://support.syncfusion.com/kb/article/11218/how-to-load-appointments-on-demand-in-flutter-calendar

Live sample: https://github.com/syncfusion/flutter-examples/blob/master/lib/samples/calendar/calendar_loadmore.dart

If you are still facing any issue, please provide the reproduced sample this will be more helpful to us to provide a solution sooner.

Regards,

Preethika Selvam.

@LavanyaGowtham2021 LavanyaGowtham2021 added waiting for customer response Cannot make further progress until the customer responds. and removed open Open labels May 22, 2024
@VijayakumarMariappan VijayakumarMariappan added open Open and removed waiting for customer response Cannot make further progress until the customer responds. labels May 23, 2024
@rmpt
Copy link
Author

rmpt commented May 23, 2024

Ok I managed to change the logic so the appointments are loaded on the handleLoadMore callback and not on the onViewChanged, but the result is the same, please have a look at the video.

agenda.mp4

I do the API call from my data source within handleLoadMore call. Data is corretcly loaded, added to appointments and notified, but the events are only shown after a minimum swipe.

Simplified code:

class AgendaDataSource extends CalendarDataSource {

  ...

  @override
  Future<void> handleLoadMore(DateTime start, DateTime end) async {
    // async API call 
    ApiCall.getEvents(start, end).then((entries) {
        appointments!.addAll(entries);
        notifyListeners(CalendarDataSourceAction.add, entries);
    });
  }
}

Does it has to do with the API call? In your examples you data is local, so all operations within handleLoadMore are sync. In my case, I'm calling the API to fetch some data and only after I have the data, I add and notify the data source. Does it make any difference?

@rmpt
Copy link
Author

rmpt commented May 24, 2024

Hi @PreethikaSelvam , I found the issue.
The problem was, before adding the entries, I was removing others that were not needed anymore and notifying to remove. It means the flow was something like:

class AgendaDataSource extends CalendarDataSource {

  ...

  @override
  Future<void> handleLoadMore(DateTime start, DateTime end) async {

    // delete unnecessary entries
    var entriesToDelete = appointments!.where(predicate).toList();
    for (var entry in entriesToDelete) {
      appointments!.remove(event);
    }
    notifyListeners(CalendarDataSourceAction.remove, entriesToDelete);

    // async API call 
    ApiCall.getEvents(start, end).then((entries) {
        appointments!.addAll(entries);
        notifyListeners(CalendarDataSourceAction.add, entries);
    });
  }
}

I had 2 sequential notifyListeners, so I guess the first one would trigger the rendering and the second one would be "ignored" until the screen is touched.

But now I have another question:
I still need to delete and add entries, what CalendarDataSourceAction should I use? reset?

@marcoancona
Copy link

marcoancona commented Aug 20, 2024

We see the same issue: the calendar view is only updated after a user input (like a tap anywhere). This feels very much like a race condition because it does not happen all the times.

@PreethikaSelvam You suggestion to use handleLoadMore does not work in all cases. What if events are updated in the background and we need to trigger a calendar update to show the new data (so not triggered by a change of view or a change of date)?

EIDT: It turns out that this was probably a race condition caused by calling calendarController.displayDate = twice in a row in a short time span. After fixing this, the problem no longer occurs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
calendar Calendar component open Open
Projects
None yet
Development

No branches or pull requests

5 participants