The BlocBuilder is not called whenever my new state is pushed. Only an item from the list of the new state differs from the current state.
To Reproduce
conversationBloc.dart
class ConversationBloc extends Bloc<ConversationEvent, ConversationState> {
final MessageRepository messageRepository = locator<MessageRepository>();
ConversationBloc();
@override
ConversationState get initialState => ConversationInitial();
@override
Stream<ConversationState> mapEventToState(ConversationEvent event) async* {
final currentState = state;
[...]
if (event is ConversationNewMessage) {
if (currentState is ConversationSuccess) {
var s = ConversationSuccess(
conversations: currentState.conversations.toList(), hasReachedMax: currentState.hasReachedMax);
var conversation = s.conversations?.firstWhere(
(c) => Extensions.equalsIgnoreCase(c.conversation.conversationId, event.message.conversationId));
if (conversation != null) {
var conversations = conversation.conversation;
conversations.messages.insert(0, event.message);
conversation = ConversationInformationResource(
conversation: conversations, unreadMessagesCount: conversation.unreadMessagesCount + 1);
}
yield s;
}
}
}
conversationState.dart
@immutable
abstract class ConversationState extends Equatable {
const ConversationState();
@override
List<Object> get props => [];
}
class ConversationInitial extends ConversationState {}
class ConversationFailure extends ConversationState {}
class ConversationSuccess extends ConversationState {
final List<ConversationInformationResource> conversations;
final bool hasReachedMax;
const ConversationSuccess({
this.conversations,
this.hasReachedMax,
});
ConversationSuccess copyWith({
List<ConversationInformationResource> conversations,
bool hasReachedMax,
}) {
return ConversationSuccess(
conversations: conversations ?? this.conversations,
hasReachedMax: hasReachedMax ?? this.hasReachedMax,
);
}
@override
List<Object> get props => [conversations, hasReachedMax];
@override
String toString() => 'PostSuccess { posts: ${conversations.length}, hasReachedMax: $hasReachedMax }';
}
conversationInformationResource.dart
@immutable
class ConversationInformationResource extends Equatable {
final ConversationResource conversation;
final int unreadMessagesCount;
ConversationInformationResource({this.conversation, this.unreadMessagesCount});
static ConversationInformationResource fromJson(Map<dynamic, dynamic> json) {
return ConversationInformationResource(
conversation: ConversationResource.fromJson(json['conversation']),
unreadMessagesCount: json['unreadMessagesCount']);
}
@override
List<Object> get props => [conversation, unreadMessagesCount];
}
conversationResource.dart
@immutable
class ConversationResource extends Equatable {
final String conversationId;
final String name;
final String imageUrl;
final bool isGroupConversation;
final String groupId;
final List<ConversationRelationResource> participants;
final List<ConversationMessageResource> messages;
ConversationResource(
{this.conversationId,
this.name,
this.imageUrl,
this.isGroupConversation,
this.groupId,
this.participants,
this.messages});
static ConversationResource fromJson(Map<String, dynamic> json) {
return ConversationResource(
conversationId: json['conversationId'],
name: json['name'],
imageUrl: json['imageUrl'],
isGroupConversation: json['isGroupConversation'],
groupId: json['groupId'],
participants: (json['participants'] as List).map((i) => ConversationRelationResource.fromJson(i)).toList(),
messages: (json['messages'] as List).map((i) => ConversationMessageResource.fromJson(i)).toList());
}
@override
List<Object> get props => [conversationId, name, imageUrl, isGroupConversation, groupId, participants, messages];
}
conversationPage.dart
@override
Widget build(BuildContext context) {
return BlocBuilder<ConversationBloc, ConversationState>(
builder: (context, state) {
[...]
if (state is ConversationSuccess) {
if (state.conversations.isEmpty) {
return Center(
child: Text('no posts'),
);
}
return ListView.separated(
separatorBuilder: (context, index) => Divider(
color: Colors.black,
),
itemBuilder: (BuildContext context, int index) {
return index >= state.conversations.length
? BottomLoader()
: ConversationWidget(conversation: state.conversations[index]);
},
itemCount: state.hasReachedMax ? state.conversations.length : state.conversations.length + 1,
controller: _scrollController,
);
}
},
);
}
Steps to reproduce the behavior:
Expected behavior
I would expect that the list would be rebuilt
Additional context
It seems that, if another state is pushed (i.e: ConversationSuccess with hasReachedMax = !currentState.hasReachedMax), then the blocbuilder is executed, but updating an item from the list doesn't.
Hi @bezaou 馃憢
Thanks for opening an issue!
Are you able to share a link to the app so I can reproduce the issue locally? I would be happy to take a look and open a pull request with suggestions, thanks! 馃憤
Hi thanks for your reply.
I think my code was not alright as I found a similar issue that was already resolved #197
We can close this ticket.
I'm also facing same issue. blocbuilder and bloclistener both are not updated
Most helpful comment
Hi thanks for your reply.
I think my code was not alright as I found a similar issue that was already resolved #197
We can close this ticket.