Repository: SimformSolutionsPvtLtd/flutter_calendar_view

Issue:
EventController.removeAll generates a concurrencymodification exception
The removeAll method causes a concurrency modification exception when you try to remove all events from the controller.

```
  _weekController
        ..removeAll(_weekController.allEvents)
        ..addAll(eventData);
```

```dart
  /// Removes all the [events] from this controller.
  void removeAll(List<CalendarEventData<T>> events) {
    for (final event in events) {
      _calendarData.removeEvent(event);
    }
    notifyListeners();
  }
```
causes a 
```
ConcurrentModificationError (Concurrent modification during iteration: Instance of 'UnmodifiableListView<CalendarEventData<JobEventEx>>'.)
```

So the issue is that I'm trying to remove all events from the controller so I can reload it.
Obviously passing in the same list of events as we are going to iterate over is always going to be an issue.

There does feel like there is an api design flaw here, because the events we need to remove are always going to be held in the controller.

A couple of solutions:
Add a 'clear' method to the api to clear the list of events from the controller - this will reduce the chance that someone will
use the api the way I did.

Have the code always iterate over a copy of the events - could be expensive give that each event holds user data.

Add a comment in the api doc to warn the user might be sufficient.




Fix patch:
diff --git a/README.md b/README.md
index 7448455f..4984a0ee 100644
--- a/README.md
+++ b/README.md
@@ -255,17 +255,18 @@ assigned.
 
 Methods provided by `EventController`
 
-| Name            | Parameters                                                   | Description                                               |
-|-----------------|--------------------------------------------------------------|-----------------------------------------------------------|
-| add             | CalendarEventData\<T\> event                                 | Adds one event in controller and rebuilds view.           |
-| addAll          | List\<CalendarEventData\<T\>\> events                        | Adds list of events in controller and rebuilds view.      |
-| remove          | CalendarEventData\<T\> event                                 | Removes an event from controller and rebuilds view.       |
-| removeAll       | List\<CalendarEventData\<T\>\> events                        | Removes all event defined in the list                     |
-| removeWhere     | TestPredicate\<CalendarEventData\<T\>\> test                 | Removes all events for which test returns true.           |
-| update          | CalendarEventData\<T\> event, CalendarEventData\<T\> updated | Updates event with updated event.                         |
-| getFullDayEvent | DateTime date                                                | Returns the list of full day events stored in controller  |
-| updateFilter    | EventFilter\<T\> newFilter                                   | Updates the event filter of the controller.               |
-| getEventsOnDay  | DateTime date                                                | Returns list of events on `date`                          |
+| Name            | Parameters                                                   | Description                                                 |
+|-----------------|--------------------------------------------------------------|-------------------------------------------------------------|
+| add             | CalendarEventData\<T\> event                                 | Adds one event in controller and rebuilds view.             |
+| addAll          | List\<CalendarEventData\<T\>\> events                        | Adds list of events in controller and rebuilds view.        |
+| remove          | CalendarEventData\<T\> event                                 | Removes an event from controller and rebuilds view.         |
+| removeAll       | List\<CalendarEventData\<T\>\> events                        | Removes all event defined in the list and rebuilds the view |
+| clear           |                                                              | Removes events from the controller and rebuilds the view    |
+| removeWhere     | TestPredicate\<CalendarEventData\<T\>\> test                 | Removes all events for which test returns true.             |
+| update          | CalendarEventData\<T\> event, CalendarEventData\<T\> updated | Updates event with updated event.                           |
+| getFullDayEvent | DateTime date                                                | Returns the list of full day events stored in controller    |
+| updateFilter    | EventFilter\<T\> newFilter                                   | Updates the event filter of the controller.                 |
+| getEventsOnDay  | DateTime date                                                | Returns list of events on `date`                            |
 
 Check [documentation](https://pub.dev/documentation/calendar_view/latest/calendar_view/EventController-class.html) for more info.
 
diff --git a/lib/src/event_controller.dart b/lib/src/event_controller.dart
index e5b73d16..f67c4b3a 100644
--- a/lib/src/event_controller.dart
+++ b/lib/src/event_controller.dart
@@ -147,6 +147,12 @@ class EventController<T extends Object?> extends ChangeNotifier {
     notifyListeners();
   }
 
+  void clear() {
+    _calendarData.clear();
+
+    notifyListeners();
+  }
+
   /// Removes multiple [event] from this controller.
   void removeWhere(TestPredicate<CalendarEventData<T>> test) {
     _calendarData.removeWhere(test);
@@ -615,5 +621,14 @@ class CalendarData<T extends Object?> {
     events.addAll(recurringEvents);
     return events;
   }
+
+  /// Remove all events from the controller.
+  void clear() {
+    _fullDayEventList.clear();
+    _rangingEventList.clear();
+    _singleDayEvents.clear();
+    _eventList.clear();
+    _recurringEventsList.clear();
+  }
   //#endregion
 }


Test patch:
diff --git a/test/src/event_controller_test.dart b/test/src/event_controller_test.dart
new file mode 100644
index 00000000..91ce5471
--- /dev/null
+++ b/test/src/event_controller_test.dart
@@ -0,0 +1,25 @@
+import 'package:calendar_view/calendar_view.dart';
+import 'package:flutter_test/flutter_test.dart';
+
+void main() {
+  testWidgets('event controller ...', (tester) async {
+    final controller = EventController();
+
+    final now = DateTime.now();
+    controller.add(CalendarEventData<String>(
+        title: 'none',
+        date: now,
+        startTime: now,
+        endTime: now.add(Duration(hours: 1))));
+    controller.add(CalendarEventData<String>(
+      title: 'All Day',
+      date: DateTime.now().withoutTime,
+    ));
+
+    expect(controller.getFullDayEvent(now).length, equals(1));
+    expect(controller.getEventsOnDay(now).length, equals(2));
+    expect(controller.allEvents.length, equals(2));
+    controller.clear();
+    expect(controller.allEvents.length, equals(0));
+  });
+}