Search code examples
flutterdartflutter-provider

flutter: Null check operator used on a null value. Unhandled Exception: RangeError (index): Invalid value: Valid value range is empty: 0


I recently migrated my App to support null safety. I used the provider package to manage my App states. Even though I check for nullability, I still face an error in my code. here is the error stack:

flutter: Null check operator used on a null value [VERBOSE-2:dart_vm_initializer.cc(41)] Unhandled Exception: RangeError (index): Invalid value: Valid value range is empty: 0 #0 List.[] (dart:core-patch/growable_array.dart:264:36) #1 Tutorials.setTutorials tutorials.dart:48 #2 _TutorialPageState.build. tutorial_page.dart:54 #3 Consumer.buildWithChild consumer.dart:179 #4 SingleChildStatelessWidget.build nested.dart:259 #5 StatelessElement.build framework.dart:5156 #6 SingleChildStatelessElement.build nested.dart:279 #7 ComponentElement.performRebuild framework.dart:5086 #8 Element.rebuild framework.dart:4805 #9 ComponentElement._firstBuild framework.dart:5068

Here is my code:

tutorials.dart

  List<Tutorial>? _items = [];
  List<Tutorial>? get items {
    return [...?_items];
  }

  List<Tutorial>? get tutsOfASection {
    return [...?_tutsOfASection];
  }

  Tutorial? findById(int id) {
    return _tutsOfASection?.firstWhere((tut) => tut.id == id);
  }   

  setTutorials(int sectionId) async {
    final List<Tutorial>? loadedTuts = [];
    var i = 0;
    debugPrint("items: ${_items?[i].pid}");
    if (_items?[i] == null) {
      return;
    } else {
      do {
        if (_items![i].pid == sectionId) {
          loadedTuts?.add(_items![i]);
        }
        i++;
      } while (_items!.length > i);
      _tutsOfASection = loadedTuts;
    }
  }

tutorial_page.dart

  body: Consumer<Tutorials>(builder: (context, value, child) {
    if (_section?["sectionId"] != null) {
      value.setTutorials(_section!["sectionId"]);
      return TutorialScreen();
    } else
      return Container();
  }),

Solution

  • I think it's actually the print that gives the error

    debugPrint("items: ${_items?[i].pid}");
    

    It will throw the exception when _items is empty. If you leave this out it might work, or rewrite it to something like

    debugPrint("items: ${(_items ?? []).isEmpty ? 'null' : _items?[i].pid}");
    

    EDIT:

    actually this check has the same problem

    if (_items?[i] == null) {
    

    this will crash if _items is empty, so change it to this for example

    if (_items == null || _items.isEmpty || _items?[i] == null) {