I would like to get todos from API, set them to state and show them on screen. On initState method I am starting request. After recieving it in my BLoC, I set it in state. But todos don't visible on my screen and state is emty array.
My request from screen:
@override
void initState() {
todosBloc.add(TodosInitialFetchEvent());
super.initState();
}
Here is my BLoC file with state:
@freezed
abstract class TodosState with _$TodosState {
const factory TodosState({
required List<Todo> todos,
@Default(false) bool loading,
}) = _TodosState;
}
class TodosBloc extends Bloc<TodosEvent, TodosState> {
TodosBloc() : super(const TodosState(todos: [])) {
on<TodosInitialFetchEvent>(todosInitialFetchEvent);
}
FutureOr<void> todosInitialFetchEvent(event, Emitter<dynamic> emit) async {
emit(state.copyWith(loading: true)); // try to set loading as true
List<Todo> todos = await TodosRepo
.getAllTodos(); // async operation to JSON placeholder API (works)
emit(state.copyWith(
todos: todos, loading: false)); // finish loading, apply recieved todos
print(state.todos); // shows todos which were recieved
}
}
Part of UI screen where I should see todos, but no:
@override
Widget build(BuildContext context) {
return Scaffold(body: BlocBuilder<TodosBloc, TodosState>(
builder: (context, state) {
print(state.todos); // shows empty array
if (state.loading) {
return const Center(
child: CircularProgressIndicator(),
);
}
The solution is that I shouldn't create another instanse of bloc to call an event
Was:
final TodosBloc todosBloc = TodosBloc();
Should be in initState:
context.read<TodosBloc>().add(event);