0

I'm making an api call using the flutter_bloc pattern when a page loads for the first time. I'm adding the event in initState and it all works fine. I'm also trying to add a refresh button. And Im doing the exact same thing as I do in the initState. But it doesn't trigger a rebuild in blocBuilder. Here Is the presentation layer.

class OtherPage extends StatefulWidget {
  @override
  _OtherPageState createState() => _OtherPageState();
}

class _OtherPageState extends State<OtherPage> {
  EngageBloc engageBloc;
  int count = 0;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          actions: <Widget>[
            IconButton(
              icon: Icon(Icons.refresh),
              onPressed: () {
                engageBloc.add(FetchEngageEvent());
              },
            ),
          ],
        ),
        body: BlocBuilder<EngageBloc, EngageState>(builder: (context, state) {
          if (state is EngageInitialState) {
            return CircularProgressIndicator();
          }
          if (state is EngageLoadingState) {
            return CircularProgressIndicator();
          }
          if (state is EngageLoadedState) {
            final courses = state.courses;
            return buildUi(courses);
          }
          if (state is EngageErrorState) {
            return buildErrorUi(state.message);
          }
          return Container();
        }));
  }

  Widget buildLoading() {
    return Center(
      child: CircularProgressIndicator(),
    );
  }

  Widget buildErrorUi(String message) {
    return Center(
      child: Padding(
        padding: const EdgeInsets.all(8.0),
        child: Text(
          message,
          style: TextStyle(color: Colors.red),
        ),
      ),
    );
  }

  Widget buildUi(AvailableCourseBoxset courses) {
    return Text('It works!!');
  }

  @override
  void initState() {
    engageBloc = BlocProvider.of<EngageBloc>(context);
    engageBloc.add(FetchEngageEvent());
    super.initState();
  }
}

IS there anything obvious I'm doing wrong. When I click the refresh button the api call is made. No error comes up in the logs. I'm using an observer that tracks state transitions. Output:

flutter: onTransition Transition { currentState: EngageLoadedState, event: FetchEngageEvent, nextState: EngageLoadingState }
flutter: onTransition Transition { currentState: EngageLoadingState, event: FetchEngageEvent, nextState: EngageLoadedState 

}

EngageLoadingState is called but the ui doesn't even update for this.. As I said initState works but doing the same for the refresh button doesn't. I appreciate I might need to add more code...Just ask and I'll post what you request..Thank you.

flutter
  • 6,188
  • 9
  • 45
  • 78

1 Answers1

0

You shouldn't store the bloc class in a variable. You should provide it with a BlocProvider and then use BlocProvider.of<EngageBloc>(context).add(FetchEngageEvent()); in order to add event the this bloc.

This is because different blocs can be setup throughout your app, you therefore want to manage them with a provider/consumer model.

In order for this to work you would although have to put the BlocProvider before your Scaffold in order to be able to access it in your appBar.

Lulupointu
  • 3,364
  • 1
  • 12
  • 28