Hi Felix,
So, I have Bloc A and Bloc B, which used in one same page. There's a functionality where I want to add an event to bloc B, after a specific event in bloc A finished. In my case there's no case where I can trigger bloc B without having to run the specific event in bloc A first.
So, to make it more straightforward for testing, I put my bloc B as a dependency of a Bloc A. (I use GetIt) Something like:
class BlocA {
final BlocB blocB;
BlocA({@required this.blocB});
mapEventToState(Event event){
// Do Something first
yield SomethingBlocAState();
// Do another thing
blocB.add(SomethingBlocBEvent());
}
}
I then use a BlocListener in my UI with MultiBlocListener.
The test is passing, but the problem is, new state from blocB after handling SomethingBlocBEvent never trigger the BlocListener in my UI code, while the state of blocA triggers its BlocListener (in one same MultiBlocListener, under one same MultiBlocProvider).
I have containerized my problem in a simplified repo. You can take a look here: https://github.com/moseskarunia/sampleapp
pubspec.yaml
name: sampleapp
description: A new Flutter project.version: 1.0.0+1
environment:
sdk: ">=2.1.0 <3.0.0"dependencies:
flutter:
sdk: flutter
get_it: ^3.0.3
equatable: ^1.1.1
flutter_bloc: ^4.0.0
firebase: ^7.3.0
image_picker: ^0.6.3+4
cupertino_icons: ^0.1.2
json_annotation: ^3.0.1dev_dependencies:
flutter_test:
sdk: flutter
build_runner: ^1.7.3
json_serializable: ^3.2.5flutter:
uses-material-design: true
Flutter Doctor
[✓] Flutter (Channel stable, v1.17.0, on Mac OS X 10.15.4 19E287, locale en-ID)
• Flutter version 1.17.0 at /Users/moseskarunia/Development/flutter
• Framework revision e6b34c2b5c (9 days ago), 2020-05-02 11:39:18 -0700
• Engine revision 540786dd51
• Dart version 2.8.1[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.2)
• Android SDK at /Users/moseskarunia/Development/Android/sdk
• Platform android-29, build-tools 29.0.2
• ANDROID_HOME = /Users/moseskarunia/Development/Android/sdk
• Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
• Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b49-5587405)
• All Android licenses accepted.[✓] Xcode - develop for iOS and macOS (Xcode 11.4.1)
• Xcode at /Applications/Xcode.app/Contents/Developer
• Xcode 11.4.1, Build version 11E503a
• CocoaPods version 1.9.1[!] Android Studio (version 3.5)
• Android Studio at /Applications/Android Studio.app/Contents
✗ Flutter plugin not installed; this adds Flutter specific functionality.
✗ Dart plugin not installed; this adds Dart specific functionality.
• Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b49-5587405)[✓] VS Code (version 1.45.0)
• VS Code at /Applications/Visual Studio Code.app/Contents
• Flutter extension version 3.10.1[✓] Connected device (1 available)
• iPhone SE (2nd generation) • B0FBD2EC-8ABD-404E-B199-CCA4285D7786 • ios •
com.apple.CoreSimulator.SimRuntime.iOS-13-4 (simulator)! Doctor found issues in 1 category.
Thanks!
Hi @moseskarunia 👋
Thanks for opening an issue!
You should register the blocs as singletons and you need to call get to retrieve them. I opened a pull request with the necessary fixes.
Hi felix, I have a follow up question.
Is it because with factory it actually initialized in different context when chained like this? Or maybe something else caused this kind of behavior?
Since i successfully able to make it work in other pages with singleton factory (as seen in reso coder's clean architecture as well), granted, without adding an event between blocs.
Thank you
When you register your blocs as factories you'll get a new instance every time get it requests your type. That means the injected notification bloc into your counter bloc will be a different instance than the existing one in the tree. So when you're adding an event on the second instance clearly is not going to trigger the listener set up for the first instance of your notification bloc. 👍
Most helpful comment
When you register your blocs as factories you'll get a new instance every time get it requests your type. That means the injected notification bloc into your counter bloc will be a different instance than the existing one in the tree. So when you're adding an event on the second instance clearly is not going to trigger the listener set up for the first instance of your notification bloc. 👍