felangel / bloc

A predictable state management library that helps implement the BLoC design pattern
https://bloclibrary.dev
MIT License
11.84k stars 3.4k forks source link

Dispatches of the same event class back to back are ignored #206

Closed tobytraylor closed 5 years ago

tobytraylor commented 5 years ago

Describe the bug Dispatches of the same event class back to back are ignored. This is due to the if (currentState == nextState) return; in Bloc._bindStateSubject.

Removing that line of code allows the same event to be submitted multiple times. The use case that i have is similar to the block with stream example where there is an inner subscription within the bloc that listens to updates to a firebase document collection. Each of these emit the same internal event class with updated data. I don't know why the system filters the same event types but a subscription solution like this requires the ability.

felangel commented 5 years ago

Hi @tobytraylor 👋

Thanks for opening an issue!

The line you're pointing out filters out duplicate states, not events. You can dispatch the same event over and over and the bloc will process it. The problem I believe you're having is when you yield a state in mapEventToState it must be a new state (you cannot mutate the currentState and yield it). Hope that answers your question. 👍

If you're still having trouble, it would be great if you could provide a sample application with the problem you're having and I'm happy to take a look 😄

Thanks!

tobytraylor commented 5 years ago

Hey. Yeah I'm not mutating the current state. I'm creating a new state object based on the stream from firestore and then populating it's members and dispatching it. I've never used Equatable before. Perhaps i need to be making all members Equatable and their nested values Equatable?

felangel commented 5 years ago

If you're extending Equatable make sure to pass props to the super class.

import 'package:equatable/equatable.dart';
import 'package:meta/meta.dart';

@immutable
abstract class DataState extends Equatable {
  DataState([List props = const []]) : super(props);
}

class MyDataState extends DataState {
  final String someProp;

  MyDataState(this.someProp) : super([someProp]); // pass the props to super
}
tobytraylor commented 5 years ago

Oh... my... god. I'm an idiot. Thanks for the help. For some reason I had read the properties list as a list of the property names, not the values. Had super(['someProp']). Thanks for helping me out there with the example. Spent close to an hour tracking down "your" issue and i just should have looked closer at the example and my code.

BTW, thanks so much for the excellent implementation of Bloc. I wrote the last app for flutter using built_values/redux and am thinking i'm going to port it's state implementation to Bloc after getting started with this. Just so much easier to manage and modularize. Have a great day man. Thanks!

felangel commented 5 years ago

No worries! I'm glad I was able to help 😄

Thanks so much for the positive feedback, I really appreciate it 👍 Have a great day!

eric-samurai commented 5 years ago

Hi @felangel ,got the same issue here, when i use a RefreshIndicator (like the Weather demo) to dispatch a new Fetch event, if the data of the next state is equal with the current state, then BlocBuilder won't be notified, and the RefreshIndicator will be loading forever. Should I avoid using Equatable for my state class and json model in this scenario?

felangel commented 5 years ago

Hi @dsmo 👋

You can definitely avoid using Equatable if you really want a rebuild even though the state hasn’t changed but I would question why you want that behavior. If nothing has changed then why do you want the UI to rebuild? It might be an issue of using Equatable properly. Can you confirm that you are passing the properties to the superclass? Thanks! 👍

hunght commented 4 years ago

@felangel in my case, i need the same event fire because when i call api, it return error message, so i need to show error message every time when api call fail, so because i use Equatable it only show the first time.

felangel commented 4 years ago

@hunght in that case it's totally fine not to extend Equatable 👍

raymond-liao commented 3 years ago

@felangel you saved me, thanks.