Hi! I'm new with flutter and I'm writing a simple app: there is an items' list and under this a TextForm to insert a new element, i type the name and click the button "add", and the element is written in firestore. This part works fine, but after this i need to reload the list to show the new element, and this is where i've the problem: i know that i can't yield the same state twice, so i yield first LoadingState (that is empty) and then LoadedListState, but the blocBuilder doesn't receive anything, i also inserted a print. I'm using flutter_bloc: 6.0.5, with older versions (4..) i didn't have this problem. What am i doing wrong?
firebaseBloc.dart
@override
Stream<FirebaseState> mapEventToState(FirebaseEvent event, ) async* {
print("event firebase ${event.runtimeType.toString()}");
if (event is CreateItemFirebaseEvent) {
yield LoadingState();
await _databaseService.createItem(event.item, event.user);
List<Item>itemsList = await _databaseService
.loadItemsList(event.user.itemsIDsList);
yield LoadedItemsListState(itemsList);
}
if (event is LoadItemsListEvent) {
List<Item> itemsList =
await _databaseService.loadItemsList(event.ItemsIDs);
yield LoadedItemsListState(itemsList);
}
firebase_state.dart
abstract class FirebaseState extends Equatable {
const FirebaseState();
}
class LoadingState extends FirebaseState {
@override
List<Object> get props => [];
}
class LoadedItemsListState extends FirebaseState {
final List<Item> itemsList;
LoadedItemsListState(this.itemsList);
@override
List<Object> get props => [];
}
screen_widget.dart
class ItemSelectionScreen extends StatefulWidget {
final User user;
ItemSelectionScreen({
@required this.user,
});
@override
_ItemSelectionScreenState createState() =>
_ItemSelectionScreenState();
}
class _ItemSelectionScreenState extends State<ItemSelectionScreen> {
FirebaseBloc _firebaseBloc;
@override
void initState() {
super.initState();
_firebaseBloc = FirebaseBloc();
_firebaseBloc.add(LoadItemsListEvent(widget.user.itemsIDsList));
}
@override
Widget build(BuildContext context) {
return BlocProvider<FirebaseBloc>(
create: (context) => _firebaseBloc,
child: Scaffold(
body: SingleChildScrollView(
child: Center(
child: BlocBuilder(
cubit: _firebaseBloc,
builder: (context, state) {
print("state ${state.runtimeType.toString()}");
if (state is LoadedItemsListState) {
return buildUI(state);
} else if (state is LoadingState) {
return CircularProgressIndicator();
} else {
return _CreateItemFormWidget(widget.user);
}
},
),
),
),
),
);
}
Column buildUI(LoadedItemsListState state) {
return Column(
children: [
_CreateItemFormWidget(widget.user),
ListView.builder(
itemBuilder: (context, index) {
return Container(
color: Colors.amber,
child: ListTile(
trailing: Text(
">",
style: TextStyle(fontSize: 20),
),
onTap: () => null,
title: Text(state.itemsList[index].name),
),
);
},
shrinkWrap: true,
itemCount: state.itemsList.length,
),
],
);
}
}
i also inserted prints, when load page the first time, the output is:
state InitialFirebaseState
event firebase LoadItemsListEvent
state LoadedItemsListState
and then, when i click add:
event firebase CreateItemFirebaseEvent
and it doesn't print anything about states. I also have inserted debug points, but it doesn't stops...
I also made this experiment: yield a WaitinState(empty state) instead of LoadedListState, and it is received. My theory is that the blocBuilder receive only the latest state when i yield more than one, and this state is LoadedListState, so it's ignored becouse is equal to the previuos state received.
What can i do to resolve?
Thanks in advance
Hi! You have to complete the getter of props to allow Bloc difference between same States or Events. I think this is the bug :)
Hi @Ozymandias93 馃憢
As @alfredobs97 pinpointed, you have pass all your props to equatable for the value equality to properly work.
class LoadedRestaurantsListState extends FirebaseState {
final List<Restaurant> restaurantsList;
LoadedRestaurantsListState(this.restaurantsList);
@override
List<Object> get props => [restaurantsList];
}
Your Restaurant should also extend Equatable.
thanks guys <3
Most helpful comment
Hi @Ozymandias93 馃憢
As @alfredobs97 pinpointed, you have pass all your props to equatable for the value equality to properly work.
Your
Restaurantshould also extendEquatable.