web-dev-qa-db-ja.com

タイプCLASSのBlocを含まないコンテキストで呼び出されたBlocProvider.of()

flutterでは、アプリケーションでBlocを使用する方法を学ぶだけで、この機能を使用して単純なログインを実装しようとしています。ビューでそれを使用するためにblocのいくつかのクラスを実装した後

このコードを使用しようとするとエラーが発生します

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

RaisedButtonの中

エラー:

BlocProvider.of()がタイプLoginListingBlocのBlocを含まないコンテキストで呼び出されました。

私の見解 :

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

テーマを見たいなら他のクラス

AppApiProviderクラス:

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

contextからloginListingBlocにアクセスする必要はありません。これは、ウィジェットツリーの上ではなく、現在のクラスに存在するためです。

変化する:

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

に:

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

エラーメッセージのためにここに来た他のすべての人:常にタイプを指定し、それらを省略しないようにしてください:

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

そしてまた

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