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!
CodePudding user response:
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 declareList<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.
CodePudding user response:
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:
You can declare the
_cities
list asList<City?>
(list of nullable City). Then methodfirstWhere
can returnnull
but you should take care aboutnull safety
, e.g: while calling element.Other way is to create a
empty City
, so in theCity
class create the static field:
.
static const empty = City(
id: 0,
no: '',
name: '',
website: '',
status: false,
);
then you can return this empty City
.