Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

flutter bloc pattern navigation back results in bad state

I have a problem/question regarding the bloc plattern with flutter. Currently, i am starting my app like this

class _MyAppState extends State<MyApp> {

@override
  Widget build(BuildContext context) {        
    return BlocProvider(
        bloc: MyBloc(),
        child: MaterialApp(
          title: "MyApp",
          home: MyHomePage(),    
          routes: {
            '/homePage': (context) => MyHomePage(),
            '/otherPage': (context) => OtherPage(),
            '/otherPage2': (context) => OtherPage2(),
            ...
          },
        ));

So that i can retrieve/access myBloc like

myBloc = BlocProvider.of(context) as MyBloc;

and the data represented by the state like

BlocBuilder<MyBlocEvent, MyObject>(
    bloc: myBloc,
    builder: (BuildContext context, MyObject myObject) {         
     ....
     var t = myObject.data;
     ....
     myBloc.onFirstEvent();
     ...
 }; 

wherever i need it.

MyBloc is implemented like this:

abstract clas MyBlocEvent {}
class FirstEvent extends MyBlocEvent {}
class SecondEvent extends MyBlocEvent {}

class MyBloc extends Bloc<MyBlocEvent , MyObject>

void onFirstEvent()
{
  dispatch(FirstEvent());
}

void onSecondEvent()
{
  dispatch(SecondEvent());
}

@override
Stream<MyObject> mapEventToState( MyObject state, MyBlocEvent event) async* {
if (event is FirstEvent) {
    state.data = "test1";
}
else if (event is SecondEvent) {
    state.otherData = 5;
}
    yield state;
}

The problem i now have, is that as soon as i change on of the state values and call

Navigator.pop(context)

to go back in the current stack, i can't change anything is the state anymore because the underlying stream seems to be closed. It fails with the message:

Another exception was thrown: Bad state: Cannot add new events after calling close"

Now this only happens after i call pop. If i only push new screens i can happily change the state data without any problems.

Am i doing something wrong regarding the Navigation here or is there something else i didn't catch regarding flutter or the bloc pattern itself?

like image 343
DerDingens Avatar asked Oct 24 '18 05:10

DerDingens


1 Answers

Bad state: Cannot add new events after calling close

This error means that you are calling add on a StreamController after having called close:

 var controller = StreamController<int>();
 controller.close();
 controller.add(42); // Bad state: Cannot add new events after calling close

It is likely related to you calling close inside the dispose method the "wrong" widget.

A good rule of thumb is to never dispose/close an object outside of the widget that created it. This ensure that you cannot use an object already disposed of.

like image 136
Rémi Rousselet Avatar answered Oct 05 '22 04:10

Rémi Rousselet