Assume we want to load a list of todos:
abstract class TodosState extends Equatable {
const TodosState();
@override
List<Object> get props => [];
}
class TodosFilteredState extends TodosState {
final List<Todo> todos;
TodosFilteredState([this.todos = const []]);
@override
List<Object> get props => [todos];
}
class TodosFilteredByCategory extends TodosEvent {
final int categoryId;
TodosFilteredByCategory(this.categoryId);
@override
List<Object> get props => [categoryId];
}
class TodosBloc extends Bloc<TodosEvent, TodosState> {
@override
Stream<TodosState> mapEventToState(TodosEvent event) async* {
// Test data
List<Todo> todos = [Todo(id = 0, categoryId = 0), Todo(id = 1, categoryId = 1)];
if (event is TodosFilteredByCategory) {
yield TodosFilteredState(todos.where((todo) => todo.categoryId == event.categoryId));
}
}
}
If I use BlocBuilder to build UI, the UI does not build with the list of filtered todos.
The problem is at the line yield TodosFilteredState(todos.where((todo) => todo.categoryId == event.categoryId));. The where() method returns Iterable<Todo> with no compile error.
To fix the problem, I must convert it to List<Todo>: yield TodosFilteredState(todos.where((todo) => todo.categoryId == event.categoryId).toList());
Expected behavior
The UI should be rebuilt without converting Iterable<Todo> to List<Todo> manually. This kind of runtime error is difficult to detect because the compiler doesn't give any complain or warning.
The same error happen when the type Map<A, B> is needed but we return a more general type Map<dynamic, dynamic>.
Hi @nguyenxndaidev 馃憢
Thanks for opening an issue!
You should override onError in your bloc if you want to handle exceptions thrown within the bloc. Let me know if that helps, thanks!
@felangel Thanks for you help!
I create a log delegate and print error/stacktrace from there and I get:
I/flutter ( 7135): type 'WhereIterable<Todo>' is not a subtype of type 'List<Todo>'
It's very useful! Thanks again.
I created an issue to improve dart compiler here https://github.com/dart-lang/sdk/issues/41155
I created an issue to improve dart compiler here dart-lang/sdk#41155
For now we can disable implicit-casts in analysis_options.yaml to get compile time error:
analyzer:
strong-mode:
implicit-casts: false
Most helpful comment
@felangel Thanks for you help!
I create a log delegate and print error/stacktrace from there and I get:
It's very useful! Thanks again.