mapEventToState not trigerring using BLOC pattern, Flutter

Viewed 984

I'm using flutter to develop an application and decides to use the bloc pattern as recommended by google, however the event I defined is never getting triggered. I defined the event to be when a check for connectivity happens a boolean is returned from the controller to the view.

Below is the relevant code

login controller.dart

import 'package:XXXXX/connection.dart';
import 'package:bloc/bloc.dart';
import 'package:connectivity/connectivity.dart';


class LoginBloc extends Bloc<Connectivity,bool> {
  @override
  bool get initialState => false;

  @override
  Stream<bool> mapEventToState(Connectivity event) async*{
    // TODO: implement mapEventToState
    switch(await event.checkConnectivity()){
      case ConnectivityResult.mobile:
      yield true;
      break;
      case ConnectivityResult.wifi:
      yield true;
      break;
      case ConnectivityResult.none:
      yield false;

    }
  }
}
class LoginWidget extends StatefulWidget {
  @override
  LoginWidgetState createState() {
    return LoginWidgetState();
  }
}

class LoginWidgetState extends State<LoginWidget> {
@override
  Widget build(BuildContext context) {
    //final _loginBloc = BlocProvider.of<LoginBloc>(context);
    const oneSec = const Duration(seconds: 1);
    //_loginBloc.add(ConnectivityResult.checkConnectivity());
    new Timer.periodic(oneSec, (Timer t) => Connectivity().checkConnectivity());
    return Scaffold(
        body: BlocProvider(
      builder: (BuildContext context) => LoginBloc(),
      child: new Form(
        key: _formKey,
        child: ListView(
          padding: EdgeInsets.only(top: 50.0),
          children: <Widget>[
            Image.asset(
              'assets/images/XXXXX_logo.jpg',
              height: 70,
              width: 100,
              alignment: Alignment.center,
            ),
            _buildTextFields(),
            _buildButtons(),
          ],
        ),
      ),
    ));
  }

  Widget _buildTextFields() {
    return new Container(
      padding: EdgeInsets.only(left: 16.0, right: 16.0),
      child: new Column(
        children: <Widget>[
          new Container(
            child: new TextFormField(
              controller: _userFilter,
              decoration: new InputDecoration(labelText: 'Username'),
              validator: (value) {
                if (value.isEmpty) {
                  return 'Username cannot be empty';
                }
                return null;
              },
            ),
          ),
          new Container(
            child: new TextFormField(
                controller: _passwordFilter,
                decoration: new InputDecoration(labelText: 'Password'),
                obscureText: true,
                validator: (value) {
                  if (value.isEmpty) {
                    return 'Password cannot be empty';
                  }
                  return null;
                }),
          )
        ],
      ),
    );
  }

  Widget _buildButtons() {
    return new Container(
      child: new Column(
        children: <Widget>[
          new RaisedButton(
              child: new Text('Login'),
              onPressed: () {
                if (_formKey.currentState.validate()) {
                  _loginPressed();
                }
              }),
          new BlocBuilder<LoginBloc, bool>(
              builder: (BuildContext context, bool state) {
            return Container(
              color: state ? Colors.greenAccent : Colors.redAccent,
              padding: EdgeInsets.all(10.0),
              child: Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  new Text(
                    state ? "Connected" : "No Internet Connection",
                    textAlign: TextAlign.center,
                  )
                ],
              ),
            );
          }),
        ],
      ),
    );
  }
1 Answers

As stated in the name of the function mapEventToState what actually does is in the response of an event added to the Bloc sink will be called and then you will be able to yield a state out, this will be received by the BlocBuilder in your UI when this happens, so in order to make this work as you expected you should probably create an Event, then instantiate your Bloc using for instance BlocProvider and dispatch an event from there.

So based on your code

    final _loginBloc = BlocProvider.of<LoginBloc>(context);
    _loginBloc.add(YourEvent());

Then in the mapEventToState

 Stream<bool> mapEventToState(LoginEvent event) async*{
    if (event is YourEvent) {
      yield YourState();
    }
Related