Flutter - The return type 'Null' isn't a 'City', as required by the closure's context

Viewed 31

I got an error when I tried to use List.firstWhere and set orElse to return null

Error shows: The return type 'Null' isn't a 'City', as required by the closure's context

Sample code below

/// city.dart

class City {
  final int id;
  final String no;
  final String name;
  final String website;
  final bool status;

  City(this.id, this.no, this.name, this.website, this.status);

  City.fromJson(Map<String, dynamic> json)
      : id = json['id'],
        no = json['no'],
        name = json['name'],
        website = json['website'],
        status = json['status'];

  Map<String, dynamic> toJson() =>
      {'id': id, 'no': no, 'name': name, 'website': website, 'status': status};
}

/// main.dart

/// declare a list variable
List<City> _cities = [];

...


_cities.firstWhere((element) => element.id == 1, orElse: () => null); // error here

Though I can use firstWhereOrNull method in package:collection and won't get any error, I want to figure out how to use firstWhere in a correct way.

Thanks for help!

2 Answers

its throw error because you declare the list is non-null value.

if we look into the function we can see the different between them.

  • firsWhereOrNull ( package:collection )

as you can see, the T? is nullable by default. so its will return null

T? firstWhereOrNull(bool Function(T element) test) {
    for (var element in this) {
      if (test(element)) return element;
    }
    return null;
  }

  • firstWhere its non-null value. data type of orElse is following based on our declared value. since you declare List<City> this is non-null value,

then when you set function orElse: () => null it will throw IterableElementError.noElement();

 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();
  }

but if you declare List<City?> the E in firstWhere now is nullable value. then it will no error.

You cannot return null because it is expected that method will return the instance of City class, which is not nullable.

You have 2 solutions:

  1. You can declare the _cities list as List<City?> (list of nullable City). Then method firstWhere can return null but you should take care about null safety, e.g: while calling element.

  2. Other way is to create a empty City, so in the City class create the static field:

.

static const empty = City(
    id: 0,
    no: '',
    name: '',
    website: '',
    status: false,
  );

then you can return this empty City.

Related