BlocProvider.of() called with a context that does not contain a Bloc of type CLASS
Asked Answered
B

2

15

in flutter i just learn how can i use Bloc on applications and i want to try to implementing simple login with this feature. after implementing some class of bloc to using that on view

i get error when i try to use this code as

BlocProvider.of<LoginListingBloc>(context).dispatch(LoginEvent(loginInfoModel: testLogin));

inside RaisedButton

Error:

BlocProvider.of() called with a context that does not contain a Bloc of type LoginListingBloc.

My view :

class _HomePageState extends State<HomePage> {
  LoginListingBloc _loginListingBloc;

  @override
  void initState() {
    super.initState();
    _loginListingBloc =
        LoginListingBloc(loginRepository: widget.loginRepository);
  }

  ...
  @override
  Widget build(BuildContext context) {
    return BlocProvider(
      bloc: _loginListingBloc,
      child: Scaffold(
        appBar: AppBar(
            elevation: 5.0, title: Text('Sample Code', style: appBarTextStyle)),
        body: Center(
          child: RaisedButton(
              child: Text(
                'click here',
                style: defaultButtonStyle,
              ),
              onPressed: () {
                BlocProvider.of<LoginListingBloc>(context).dispatch(LoginEvent(loginInfoModel: testLogin));
              }),
        ),
      ),
    );
  }
}

LoginListingBloc class:

class LoginListingBloc extends Bloc<LoginListingEvent, LoginListingStates> {
  final LoginRepository loginRepository;

  LoginListingBloc({this.loginRepository});

  @override
  LoginListingStates get initialState => LoginUninitializedState();

  @override
  Stream<LoginListingStates> mapEventToState(
      LoginListingStates currentState, LoginListingEvent event) async* {
    if (event is LoginEvent) {
      yield LoginFetchingState();
      try {
        final loginInfo = await loginRepository.fetchLoginToPage(
            event.loginInfoModel.username, event.loginInfoModel.password);
        yield LoginFetchedState(userInfo: loginInfo);
      } catch (_) {
        yield LoginErrorState();
      }
    }
  }
}

and other classes if you want to see theme

AppApiProvider class:

class AppApiProvider {
  final successCode = 200;

  Future<UserInfo> fetchLoginToPage(String username, String password) async {
    final response = await http.get(Constants.url + "/api/v1/getPersons");
    final responseString = jsonDecode(response.body);
    if (response.statusCode == successCode) {
      print(responseString);
      return UserInfo.fromJson(responseString);
    } else {
      throw Exception('failed to get information');
    }
  }
}

LoginEvent:

class LoginEvent extends LoginListingEvent {
  final LoginInfoModel loginInfoModel;

  LoginEvent({@required this.loginInfoModel}) : assert(loginInfoModel != null);
}

LoginInfoModel:

class LoginInfoModel {
  String username;
  String password;

  LoginInfoModel({this.username, this.password});
}

final testLogin = LoginInfoModel(username:'exmaple',password:'text');
Buffon answered 12/5, 2019 at 8:29 Comment(0)
C
8

No need to access loginListingBloc from context since it exists in the current class and not up the widget tree.

change:

BlocProvider.of<LoginListingBloc>(context).dispatch(LoginEvent(loginInfoModel: testLogin));  

to:

_loginListingBloc.dispatch(LoginEvent(loginInfoModel: testLogin));
Cutlet answered 12/5, 2019 at 9:14 Comment(2)
could you help me on this topic? https://stackoverflow.com/q/56207806/1830228 thanksBuffon
The whole idea of the BLoC pattern is to separate UI from business logic. If the BLoC is instantiated inside the widget, there is no possibility of mocking it in a widget test. I highly discourage one from doing it like that. The dependencies should be injected into the widget not the other way around!Beguin
S
6

For all others who come here for the error message: Make sure you always specify the types and don't omit them:

BlocProvider<YourBloc>(
    create: (context) => YourBloc()
    child: YourWidget()
);

and also for

BlocProvider.of<YourBloc>(context);
Sismondi answered 4/2, 2020 at 19:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.