Closed jiyarong closed 5 years ago
business logic should be done in the BLoC (which actually stands for business logic component). your api service is a provider, not a bloc, a bloc should use the provider and dispatch events accordingly. check the architecture documentation here https://felangel.github.io/bloc/#/architecture
Hi @jiyarong 👋 Thanks for opening an issue!
To provide a global instance of a bloc you should use BlocProvider
at the root of your widget tree
@override
Widget build(BuildContext context) {
return BlocProvider<MyBloc>(
builder: (context) => MyBloc(),
child: MaterialApp(...),
);
}
Then from anywhere in your app you can access the bloc via BuildContext
like:
BlocProvider.of<MyBloc>(context);
Hope that helps and as @bigworld12 mentioned, this is all covered in the bloc documentation 👍
I cannot get context in my api_service.dart, that's the point
@jiyarong you should be injecting the bloc into your ApiService
via the constructor instead of directly trying to access it via BuildContext
.
class MyWidget extends StatefulWidget {
@override
State<MyWidget createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
ApiService _apiService;
@override
void initState() {
super.initState();
_apiService = ApiService(myBloc: BlocProvider.of<MyBloc>(context));
}
@override
Widget build(BuildContext context) { ... }
}
Also like @bigworld12 mentioned, what you're doing is not standard. You should be injecting the ApiService (Repository) into your Bloc not the other way around.
@jiyarong you should be injecting the bloc into your
ApiService
via the constructor instead of directly trying to access it viaBuildContext
.class MyWidget extends StatefulWidget { @override State<MyWidget createState() => _MyWidgetState(); } class _MyWidgetState extends State<MyWidget> { ApiService _apiService; @override void initState() { super.initState(); _apiService = ApiService(myBloc: BlocProvider.of<MyBloc>(context)); } @override Widget build(BuildContext context) { ... } }
Also like @bigworld12 mentioned, what you're doing is not standard. You should be injecting the ApiService (Repository) into your Bloc not the other way around.
This is my main.dart
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
MyApp({Key key}) : super(key: key);
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return BlocProvider<UserBloc>(
builder: (context) => UserBloc(),
child: Provider(
builder: (_) => MyService.create(userBloc: BlocProvider.of<UserBloc>(context)),
dispose: (context, MyService service) => service.client.dispose(),
child: MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
onGenerateRoute: RouteGenerator.generateRoute,
home: Root())));
}
}
I got some errors:
I/flutter (11393): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter (11393): The following assertion was thrown building Builder:
I/flutter (11393): BlocProvider.of() called with a context that does not contain a Bloc of type UserBloc.
I/flutter (11393): No ancestor could be found starting from the context that was passed to
I/flutter (11393): BlocProvider.of
why you have builder: (_) =>
instead of builder: (context) =>
?
I want dispatch an event in my api_serivice.dart when api response auth failed, just like
But I cannot get userBloc in my api_serivice.dart like
I try to import a new Userbloc in my api_serivice.dart and I dispatch an event
But this Userbloc obviously not equal to another one
Please help me