Describe the bug
I have recently come across the following issue in my project. With this configuration of bloc, state and event classes state changes occur in the BLoC but are not properly emitted. If I add an event to the BLoC, it is registered and the state is changed as expected, but the new state is not emitted.
````dart
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State
final TestBloc testBloc = TestBloc();
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'State Demo',
home: BlocBuilder
bloc: testBloc,
builder: (context, state) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
(state as IdleState).entries.toString(),
),
SizedBox(height: 20),
FlatButton(
child: Text("Add Entry"),
onPressed: () => testBloc.add(
AddEntryEvent(
Random().nextInt(100000),
Random().nextInt(100000),
),
),
)
],
),
),
);
}),
);
}
@override
void dispose() {
testBloc.close();
super.dispose();
}
}
````
````dart
class TestBloc extends Bloc
@override
TestState get initialState => IdleState(HashMap());
@override
Stream
if(event is AddEntryEvent && state is IdleState){
HashMap
newEntries[event.index] = event.entry;
yield IdleState(newEntries);
}
}
}
````
````dart
abstract class TestState extends Equatable {
const TestState();
}
class IdleState extends TestState {
final HashMap
IdleState(this.entries);
@override
List
````dart
abstract class TestEvent extends Equatable {
const TestEvent();
}
class AddEntryEvent extends TestEvent{
final int index;
final dynamic entry;
AddEntryEvent(this.index, this.entry);
@override
List
}
````
Expected behavior
I would expect the UI to update after adding the AddEntryEvent to the TestBloc.
Screenshots
The UI only updates after a hot-reload.

Logs
No issues found! (ran in 3.1s)
````
[√] Flutter (Channel dev, 1.18.0-10.0.pre, on Microsoft Windows [Version 10.0.18363.815], locale en-GB)
• Flutter version 1.18.0-10.0.pre at C:\Users\sebas\Documents\Coding\flutter
• Framework revision 9b7b9d795e (2 days ago), 2020-05-05 12:09:51 -0700
• Engine revision 33d2367950
• Dart version 2.9.0 (build 2.9.0-5.0.dev 9c94f08410)
[!] Android toolchain - develop for Android devices (Android SDK version 29.0.2)
• Android SDK at C:\Users\sebas\Documents\SDKs
• Platform android-29, build-tools 29.0.2
• ANDROID_HOME = C:\Users\sebas\Documents\SDKs
• Java binary at: C:\Program Files\Android\Android Studio\jre\bin\java
• Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b03)
X Android license status unknown.
Try re-installing or updating your Android SDK Manager.
See https://developer.android.com/studio/#downloads or visit visit
https://flutter.dev/docs/get-started/install/windows#android-setup for detailed instructions.
[!] Android Studio (version 3.5)
• Android Studio at C:\Program Files\Android\Android Studio
X Flutter plugin not installed; this adds Flutter specific functionality.
X Dart plugin not installed; this adds Dart specific functionality.
• Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b03)
[!] IntelliJ IDEA Community Edition (version 2019.3)
• IntelliJ at C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2019.3.4
X Flutter plugin not installed; this adds Flutter specific functionality.
X Dart plugin not installed; this adds Dart specific functionality.
• For information about installing plugins, see
https://flutter.dev/intellij-setup/#installing-the-plugins
[√] VS Code (version 1.44.2)
• VS Code at C:\Users\sebas\AppData\Local\Programs\Microsoft VS Code
• Flutter extension version 3.10.1
[√] Connected device (1 available)
• Android SDK built for x86 • emulator-5554 • android-x86 • Android 10 (API 29) (emulator)
! Doctor found issues in 3 categories.`
````
Hi @Fasust ! ✌
Looks like you're mutating the existing state thus your new states are not exiting the bloc.
To avoid this please use the following approach:
HashMap<int, dynamic> newEntries = (state as IdleState).entries;
yield IdleState(
HashMap<int, dynamic>.from(newEntries)
..addAll({event.index: event.entry}),
);
I've also noticed in your IdleState your props override utilizes .toString() on entries, which is not necessary. Although value equality will work, you could simply have it like:
@override
List<Object> get props => [entries];
Hope that gives you a better understanding of the issue you're facing 👍
Thank you @RollyPeres 😁,
yes, copying the state using .from() did the trick.
Thanks a lot for the help and the clear explanation of the problem.
Most helpful comment
Thank you @RollyPeres 😁,
yes, copying the state using
.from()did the trick.Thanks a lot for the help and the clear explanation of the problem.