196

I am running list.firstWhere and this is sometimes throwing an exception:

Bad State: No element

When the exception was thrown, this was the stack:
#0      _ListBase&Object&ListMixin.firstWhere (dart:collection/list.dart:148:5)

I do not understand what this means an also could not identify the issue by looking at the source.

My firstWhere looks like this:

list.firstWhere((element) => a == b);
creativecreatorormaybenot
  • 114,516
  • 58
  • 291
  • 402
  • In my case it generally happens due to no element/data i,e empty values on variable. So to avoid these issues , assign some values to variable like this. var artist = 'Artist'.obs; – Rahul Kushwaha Feb 17 '23 at 05:08

7 Answers7

402

This will happen when there is no matching element, i.e. when a == b is never true for any of the elements in list and the optional parameter orElse is not specified.

You can also specify orElse to handle the situation:

list.firstWhere((a) => a == b, orElse: () => print('No matching element.'));

If you want to return null instead when there is no match, you can also do that with orElse:

list.firstWhere((a) => a == b, orElse: () => null);

package:collection also contains a convenience extension method for the null case (which should also work better with null safety):

import 'package:collection/collection.dart';

list.firstWhereOrNull((element) => element == other);

See firstWhereOrNull for more information. Thanks to @EdwinLiu for pointing it out.

creativecreatorormaybenot
  • 114,516
  • 58
  • 291
  • 402
20

Now you can import package:collection and use the extension method firstWhereOrNull

import 'package:collection/collection.dart';

void main() {

  final myList = [1, 2, 3];

  final myElement = myList.firstWhereOrNull((a) => a == 4);

  print(myElement); // null
}
Edwin Liu
  • 7,413
  • 3
  • 28
  • 27
16

firstWhere retuns the newList which generated based on the condition

void main() {
  List<String> list = ['red', 'yellow', 'pink', 'blue'];
  var newList = list.firstWhere((element) => element == 'green', 
      orElse: () => 'No matching color found');
  print(newList);
}

Output:

No matching color found

OR

 void main() {
      List<String> list = ['red', 'yellow', 'pink', 'blue'];
      var newList = list.firstWhere((element) => element == 'blue', 
          orElse: () => 'No matching color found');
      print(newList);
    }

Output:

blue

If orElse not defined in the code and the wrong item gets search which doesn't exist in the list then it shows BadStateException

 void main() {
      List<String> list = ['red', 'yellow', 'pink', 'blue'];
      var newList = list.firstWhere((element) => element == 'green');
      print(newList);
    }

Output:

Uncaught Error: Bad state: No element
Jitesh Mohite
  • 31,138
  • 12
  • 157
  • 147
4

On dart 2.10 there is a new feature called null-safety and can do magic for you when you have a list of objects and you want to do something to one particular object's property:

class User {
   String name;
   int age;

  User(this.name, this.age);

   @override
   String toString() {
   return  'name:$name, age:$age';
   }

}

void main() {
  List<User?> users = [User("Ali", 20), User("Mammad", 40)];
  print(users.toString()); // -> [name:Ali, age:20, name:Mammad, age:40]
  // modify user age who it's name is Ali:
  users.firstWhere((element) => element?.name == "Ali")?.age = 30;
  print(users.toString()); // -> [name:Ali, age:30, name:Mammad, age:40]
  // modify a user that doesn't exist:
  users.firstWhere((element) => element?.name == "AliReza", orElse: ()=> null)?.age = 30; // doesn't find and works fine
  print(users.toString()); // -> [name:Ali, age:30, name:Mammad, age:40]

}

Alireza Akbari
  • 2,153
  • 2
  • 28
  • 53
3

The firstWhere() implementation looks something like below:

  E firstWhere(bool test(E element), {E orElse()?}) {
    for (E element in this) {
      if (test(element)) return element;
    }
    if (orElse != null) return orElse();
    throw IterableElementError.noElement();
  }

So as you can see, if the orElse arg is defined the method will use that and will not throw any exception if none of the elements match the condition. So use the below code to handle the erro case:

list.firstWhere((element) => a == b, orElse: () => null); // To return null if no elements match
list.firstWhere((element) => a == b, orElse: () => print('No elements matched the condition'));
Sisir
  • 4,584
  • 4
  • 26
  • 37
1

You need to check the itemCount parameter of relevant list. For example: itemCount: snapshot.data?.docs.length if your itemcount is just like above, you must check nullsafety first and after that check nullability. You itemcount may be like as follows. itemCount: snapshot.data?.docs.length ?? 0,

of course in StreamBuilder you can use singleOrNull : snapshot.data!.docs.singleOrNull!['X'],

algor
  • 67
  • 2
1

I had this problem when I used .firstpropery with an empty array.

To fixed this, just check if the array is empty or not before using .first:

Example:

 OrderAddress(
        address: addressRepository.items.isEmpty
            ? null
            : addressRepository.items.first,
      ),

enter image description here

ahmnouira
  • 1,607
  • 13
  • 8