Open zash80 opened 4 years ago
Re-open, closed by accident...
@zash80 Can you let me know where are you providing
the WeatherBloc
in you application?
@gurleensethi , see here: https://github.com/zash80/flutter-bloc-library-v1-tutorial/blob/master/lib/main.dart - WeatherBloc is set up through BlocProvider as 'home' in MaterialApp.
Hi @zash80 I took a quick look and the problem is the SailorRoute
gives you access to the new route's BuildContext
instead of the existing BuildContext
.
SailorRoute(
name: '/details',
builder: (context, args, params) {
print('context... $context'); // this context is already the new route context
return BlocProvider.value(
value: BlocProvider.of<WeatherBloc>(context),
child: WeatherDetailPage(
masterWeather: params.param('masterWeather'),
),
);
},
params: [
SailorParam<Weather>(
name: 'masterWeather',
),
],
),
I believe in order to fix this you would need to modify Sailor
to provide the BuildContext
of the current widget before the route is pushed.
Hope that helps 👍
To avoid such weird things, I do not Use provider inside router definition, rather I'm using args to pass the data to the page so in the end the definition look slike this
SailorRoute(
name: '/rss-items/filtered',
builder: (context, args, params) {
return RssItemsFilteredPage(args: args);
},
),
where args are
class RssItemsFilteredPageArgs extends BaseArguments {
final String keywords;
final Function onInit;
RssItemsFilteredPageArgs({
this.keywords,
@required this.onInit,
});
}
and the navigation call looks like this
onTap: () {
Routes.sailor(
'/rss-items/filtered',
args: RssItemsFilteredPageArgs(
keywords: item.keywords,
onInit: (keywords) {
StoreProvider.of<AppState>(context)
.dispatch(GetFilteredItemsAction(item));
StoreProvider.of<AppState>(context)
.dispatch(SetSelectedFilterAction(item));
},
),
);
}
I am experiencing a similar issue when trying to instantiate a new Bloc in a SailorRoute.builder
.
Here is a snippet of the relevant SailorRoute
.
...
SailorRoute(
name: myPage,
builder: (BuildContext context, BaseArguments args, _) {
print('DEBUG_1: creating BlocProvider for MyBloc');
return BlocProvider<MyBloc>(
create: (_) {
print('DEBUG_2: creating MyBloc');
return MyBloc();
},
child: MyPage(),
);
}),
...
When the route is pushed, the DEBUG_1 message is printed and the DEBUG_2 message is not, indicating that the BlocProvider.create
method is not run.
With this snippet, in MyPage.build
, BlocProvider.of(context)
throws.
Ideally, the BlocProvider.create
method should be run when the route is pushed, and BlocProvider.of(context)
should return the instance of MyBloc
.
Is there any other idiomatic approach to inject a Bloc using SailorRoute
?
@sterrenburg have you tried setting lazy
to false on the BlocProvider
?
...
SailorRoute(
name: myPage,
builder: (BuildContext context, BaseArguments args, _) {
print('DEBUG_1: creating BlocProvider for MyBloc');
return BlocProvider<MyBloc>(
lazy: false,
create: (_) {
print('DEBUG_2: creating MyBloc');
return MyBloc();
},
child: MyPage(),
);
}),
...
@sterrenburg have you tried setting
lazy
to false on theBlocProvider
?... SailorRoute( name: myPage, builder: (BuildContext context, BaseArguments args, _) { print('DEBUG_1: creating BlocProvider for MyBloc'); return BlocProvider<MyBloc>( lazy: false, create: (_) { print('DEBUG_2: creating MyBloc'); return MyBloc(); }, child: MyPage(), ); }), ...
Thank you! Adding lazy: false
seems to work, and correctly handles BlocProvider.of<MyBloc>(context)
in MyPage
.
I'm trying to use Sailor with flutter_bloc. When adding a SailorRoute like this:
Seeing following exception:
For details see https://github.com/zash80/flutter-bloc-library-v1-tutorial forked from https://github.com/ResoCoder/flutter-bloc-library-v1-tutorial replacing flutter navigation with Sailor navigation.