Flutter bloc: updating the state does not re-call BlocBuilder
4,746
The problem is here:
...
onTap: () {
...
HomeBloc().getAllCats();
...
},
...
It should be _homeBloc.getAllCats();
Author by
Mahmoud Mabrouk
Updated on December 13, 2022Comments
-
Mahmoud Mabrouk over 1 year
I have a page being managed using bloc
here is the
home_state.dart
import 'package:banha/data/models/category.dart'; import 'package:flutter/material.dart'; abstract class HomeState { HomeState() : super(); } class HomeInitial extends HomeState {} class UpdateCats extends HomeState { final List<Category> cats; final int rand; UpdateCats({@required this.cats,@required this.rand}){ print(this.cats); print(this.rand); } }
and the
home_bloc.dart
(note: the Random number is just to make sure the state is diff from the prev one)import 'dart:math'; import 'package:banha/data/models/category.dart'; import 'package:banha/data/network/categories.dart'; import 'package:banha/ui/tabs/home/bloc/home_events.dart'; import 'package:banha/ui/tabs/home/bloc/home_states.dart'; import 'package:bloc/bloc.dart'; class HomeBloc extends Bloc<HomeEvents, HomeState> { getAllCats() { dispatch(HomeGetCategories()); } HomeBloc() : super(); @override HomeState get initialState => HomeInitial(); @override Stream<HomeState> mapEventToState(HomeEvents event) async* { if (event is HomeGetCategories) { yield* _getCats(); } } Stream<HomeState> _getCats() async* { print("getting cats"); List<Category> newCats; await Network_getAllCategories().then((List<Category> cats) { newCats = cats; }); yield UpdateCats(cats: newCats, rand: Random().nextInt(21312545)); } }
and the page widget:
import 'package:banha/ui/category/category.dart'; import 'package:banha/ui/tabs/home/bloc/home_bloc.dart'; import 'package:banha/ui/tabs/home/bloc/home_states.dart'; import 'package:flutter/material.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class ListingsWidget extends StatefulWidget { @override _ListingsWidgetState createState() => _ListingsWidgetState(); } class _ListingsWidgetState extends State<ListingsWidget> { final HomeBloc _homeBloc = HomeBloc(); @override void initState() { super.initState(); } @override Widget build(BuildContext context) { return Container( height: 130, padding: EdgeInsets.only(top: 10, bottom: 10), child: BlocListener( bloc: _homeBloc, listener: (context, state) { print(state); }, child: BlocBuilder<HomeBloc, HomeState>( bloc: _homeBloc, builder: (BuildContext context,HomeState state) { if(state is UpdateCats){ print(state.cats); } return ListView( scrollDirection: Axis.horizontal, children: <Widget>[ InkWell( borderRadius: BorderRadius.circular(1000), onTap: () { HomeBloc().getAllCats(); // Navigator.push(context, CupertinoPageRoute(builder: (context) => CategoryPage())); }, ....
the issue is that in the view(Widget) BlocBuilder is just being called once on initial, but when I try to test changing the state using
HomeBloc().getAllCats();
and then print the new State using this code:if(state is UpdateCats){ print(state.cats); }
nothing happens (Builder is not being called ever again), what's wrong with my code?
-
Tokenyet over 4 yearsIm not sure why, but have you tried BlocDelegate to see the state transition, that would be very helpful on debugging If you could provide the logs from this.
-
-
Tokenyet over 4 yearsI just found out you did a strange thing in your code.
HomeBloc().getAllCats();
, you use a local bloc but init a new bloc when dispatching an event.BlocProvider
is not the real issue since you use local bloc. -
Mahmoud Mabrouk over 4 years@Tokenyet Exactly