'RangeError (index): Invalid value: Not in range 0..30, inclusive: -1 Flutter
I'm getting this error at first build of the ScrollablePositionedList (which is a calendar).
Initially I declare an empty List<DateTime> calendar = []; that gets filled with dates with the state (I'm using flutter_bloc) and call a method that checks if today's date is in the list and scroll to that index, otherwise scrolls to index 0 (1st day of the month).
Apart from the Bloc's InitialState which is empty, I have two different states, one is TodayDate used for building the widget on current month when screen loads, and the other is NewDate, which is used to rebuild widget when changing month in the calendar.
I get the error only when TodayDate state is received (see Print 1), but when changing month everything works as expected(see Print 2 and 3).
I can't spot why on the first widget build it throws the error as the available data is the same as print 3.
I initially thought it might had to do with the InitialState being empty but then TodayDate state comes in with data and should fix the error. Also, prints show the error after State transaction.
Can you see anything wrong in my implementation? As always thank you very much for your time and help.
Widget:
Expanded(
// child: ListView.builder(
// controller: scrollController,
child: ScrollablePositionedList.builder(
itemScrollController: scrollController,
itemCount: calendar.length,
itemBuilder: (BuildContext context, int index) =>
CalendarCell(
day: calendarFormat
.format(calendar[index]),
borderColor: isSelectedDay[index] == true
? Colors.white
: dateCheckIsToday.format(
calendar[index]) ==
dateCheckIsToday
.format(DateTime.now())
? Colors.greenAccent
: getDayNameShort.format(
calendar[index]) ==
'Sun'
? Colors.redAccent
: Colors.orangeAccent,
isSelected: isSelectedDay[index],
onTap: () {
BlocProvider.of<CalendarBloc>(context)
.add(UpdateCalendarSelectedDay(
isSelectedDay, index));
BlocProvider.of<CalendarBloc>(context)
.add(GetOpeningTimeSlots(
weekday:
'${getDayNameShort.format(calendar[index])}',
date: calendar[index]));
},
),
flex: 2,
),
BlocListener:
if (state is TodayDate) {
setState(() {
displayDate = state.newDate;
print(displayDate);
calendar = state.calendar;
isSelectedDay = state.isSelectedDay;
scrollToIndex(
calendar);
// RangeError (index): Invalid value: Not in range 0..30, inclusive: -1
});
}
if (state is NewDate) {
setState(() {
displayDate = state.newDate;
calendar = state.calendar;
isSelectedDay = state.isSelectedDay;
scrollToIndex(calendar); // works perfectly
// print('calendar is ${state.calendar}');
// print('isDaySelectedDay is ${state.isSelectedDay}');
});
}
scrollToIndex method:
void scrollToIndex(List<DateTime> calendar) {
print('scrollToIndex called');
indexToScrollTo = 0;
for (int index = 0; index < calendar.length; index++) {
dateCheckIsToday.format(DateTime.now());
if (dateCheckIsToday.format(calendar[index]) ==
dateCheckIsToday.format(DateTime.now())) {
indexToScrollTo = index;
break;
}
}
print('indexToScrolTo is: $indexToScrollTo');
scrollController.jumpTo(
index: indexToScrollTo); //, duration: Duration(seconds: 1));
}
Print 1: TodayDatestate prints for actual month of May:
flutter: Event is GetMonth : {actual date :2020-05-17 08:08:41.044548}
flutter: Transaction is Transition { currentState: InitialState : { date: 2000-01-01 00:00:00.000, calendar : [], isSelected :[]}, event: GetMonth : {actual date :2020-05-17 08:08:41.044548}, nextState: TodayDate : { date: 2020-05-17 08:08:41.044548, calendar : [2020-05-01 00:00:00.000, 2020-05-02 00:00:00.000, 2020-05-03 00:00:00.000, 2020-05-04 00:00:00.000, 2020-05-05 00:00:00.000, 2020-05-06 00:00:00.000, 2020-05-07 00:00:00.000, 2020-05-08 00:00:00.000, 2020-05-09 00:00:00.000, 2020-05-10 00:00:00.000, 2020-05-11 00:00:00.000, 2020-05-12 00:00:00.000, 2020-05-13 00:00:00.000, 2020-05-14 00:00:00.000, 2020-05-15 00:00:00.000, 2020-05-16 00:00:00.000, 2020-05-17 00:00:00.000, 2020-05-18 00:00:00.000, 2020-05-19 00:00:00.000, 2020-05-20 00:00:00.000, 2020-05-21 00:00:00.000, 2020-05-22 00:00:00.000, 2020-05-23 00:00:00.000, 2020-05-24 00:00:00.000, 2020-05-25 00:00:00.000, 2020-05-26 00:00:00.000, 2020-05-27 00:00:00.000, 2020-05-28 00:00:00.000, 2020-05-29 00:00:00.000, 2020-05-30 00:00:00.0<…>
flutter: 2020-05-17 08:08:41.044548
flutter: scrollToIndex called
flutter: indexToScrolTo is: 16
════════ (4) Exception caught by widgets library ═══════════════════════════════════════════════════
RangeError (index): Invalid value: Not in range 0..30, inclusive: -1
════════════════════════════════════════════════════════════════════════════════════════════════════
Print 2:NewDatestate when changing month to June:
flutter: Event is NextMonth : {actual date :2020-05-17 08:08:41.044548}
flutter: Transaction is Transition { currentState: TodayDate : { date: 2020-05-17 08:08:41.044548, calendar : [2020-05-01 00:00:00.000, 2020-05-02 00:00:00.000, 2020-05-03 00:00:00.000, 2020-05-04 00:00:00.000, 2020-05-05 00:00:00.000, 2020-05-06 00:00:00.000, 2020-05-07 00:00:00.000, 2020-05-08 00:00:00.000, 2020-05-09 00:00:00.000, 2020-05-10 00:00:00.000, 2020-05-11 00:00:00.000, 2020-05-12 00:00:00.000, 2020-05-13 00:00:00.000, 2020-05-14 00:00:00.000, 2020-05-15 00:00:00.000, 2020-05-16 00:00:00.000, 2020-05-17 00:00:00.000, 2020-05-18 00:00:00.000, 2020-05-19 00:00:00.000, 2020-05-20 00:00:00.000, 2020-05-21 00:00:00.000, 2020-05-22 00:00:00.000, 2020-05-23 00:00:00.000, 2020-05-24 00:00:00.000, 2020-05-25 00:00:00.000, 2020-05-26 00:00:00.000, 2020-05-27 00:00:00.000, 2020-05-28 00:00:00.000, 2020-05-29 00:00:00.000, 2020-05-30 00:00:00.000, 2020-05-31 00:00:00.000], isSelected :[false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, fals<…>
flutter: scrollToIndex called
flutter: indexToScrolTo is: 0
Print 3: NewDate prints for changing month back to May:
flutter: Event is PreviousMonth :{actual date :2020-06-17 00:00:00.000}
flutter: Transaction is Transition { currentState: NewDate : { date: 2020-06-17 00:00:00.000, calendar : [2020-06-01 00:00:00.000, 2020-06-02 00:00:00.000, 2020-06-03 00:00:00.000, 2020-06-04 00:00:00.000, 2020-06-05 00:00:00.000, 2020-06-06 00:00:00.000, 2020-06-07 00:00:00.000, 2020-06-08 00:00:00.000, 2020-06-09 00:00:00.000, 2020-06-10 00:00:00.000, 2020-06-11 00:00:00.000, 2020-06-12 00:00:00.000, 2020-06-13 00:00:00.000, 2020-06-14 00:00:00.000, 2020-06-15 00:00:00.000, 2020-06-16 00:00:00.000, 2020-06-17 00:00:00.000, 2020-06-18 00:00:00.000, 2020-06-19 00:00:00.000, 2020-06-20 00:00:00.000, 2020-06-21 00:00:00.000, 2020-06-22 00:00:00.000, 2020-06-23 00:00:00.000, 2020-06-24 00:00:00.000, 2020-06-25 00:00:00.000, 2020-06-26 00:00:00.000, 2020-06-27 00:00:00.000, 2020-06-28 00:00:00.000, 2020-06-29 00:00:00.000, 2020-06-30 00:00:00.000],isSelected :[false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, <…>
flutter: scrollToIndex called
flutter: indexToScrolTo is: 16
As prints show when when changing month and receiving NewDate state the widget updates correctly and when changing back to actual month it also behaves as expected jumping to today's date. So why does TodayDate fail, that carries same data, and does the same call to the scroll method as NewDate?
Update:
Using a Timer to delay the call of the scrollToIndex method makes it work properly. Hope this helps to understand where the problem is.
if (state is TodayDate) {
setState(() {
displayDate = state.newDate;
print(displayDate);
calendar = state.calendar;
isSelectedDay = state.isSelectedDay;
Timer(Duration(milliseconds: 50), () {
scrollToIndex(calendar);
});
// timer makes it work
// RangeError (index): Invalid value: Not in range 0..30, inclusive: -1
});
// scrollToIndex(calendar);
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
