web-dev-qa-db-fra.com

BlocProvider.of () appelé avec un contexte qui ne contient pas de bloc de type CLASS

en flutter, j'apprends juste comment utiliser Bloc sur les applications et je veux essayer d'implémenter une connexion simple avec cette fonctionnalité. après avoir implémenté une classe de bloc pour l'utiliser sur la vue

j'obtiens une erreur lorsque j'essaie d'utiliser ce code comme

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

à l'intérieur RaisedButton

Erreur:

BlocProvider.of () appelé avec un contexte qui ne contient pas de bloc de type LoginListingBloc.

Mon avis :

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 classe:

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();
      }
    }
  }
}

et d'autres classes si vous voulez voir le thème

AppApiProvider classe:

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');
8
DolDurma

Pas besoin d'accéder à loginListingBloc depuis context car il existe dans la classe courante et non dans l'arborescence des widgets.

changement:

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

à:

_loginListingBloc.dispatch(LoginEvent(loginInfoModel: testLogin));
4
nonybrighto

Pour tous les autres qui viennent ici pour le message d'erreur: assurez-vous de toujours spécifier les types et ne les omettez pas:

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

et aussi pour

BlocProvider.of<YourBloc>(context);
0
luckyhandler