Bloc: BlocBuilder is not called on updated state

Created on 11 Jul 2020  路  3Comments  路  Source: felangel/bloc

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:

  1. Check the conversations page. the conversations are displayed correctly
  2. Whenever a new message come, the list is not rebuilt

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.

question

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.

All 3 comments

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

Was this page helpful?
0 / 5 - 0 ratings