Bloc: Correct use of multiple blocs when building widgets

Created on 24 Apr 2019  路  5Comments  路  Source: felangel/bloc

@felangel great stuff. Most examples though cover quite simple data relationships, e.g. a list and a filter on that list, or a list and an aggregate on that list. I'm not always sure however where the pieces go with data joins e.g. Product-Buyer-Order.

In the below, I'd like to rebuild UI on Foo changes and reference data from Bar in doing so. Would you say this looks about right?

@override
Widget build(BuildContext context) {
  var fooBloc = BlocProvider.of<FooBloc>(context);
  var barBloc = BlocProvider.of<BarBloc>(context);
  var barState = barBloc.currentState;
  return BlocBuilder<BlocEvent, BlocState>(
      bloc: fooBloc,
      builder: (BuildContext context, BlocState fooState) {
        if (fooState is FooUpdated && barState is BarUpdated) {
          // use fooState and barState to build UI
        }
      });
}

If I wanted to update UI given changes in either Foo or Bar, I'd presumably need to nest BlocBuilders, e.g. would this look about right?:

@override
Widget build(BuildContext context) {
  var fooBloc = BlocProvider.of<FooBloc>(context);
  return BlocBuilder<BlocEvent, BlocState>(
      bloc: fooBloc,
      builder: (BuildContext context, BlocState fooState) {
        if (fooState is FooUpdated) {
          var barBloc = BlocProvider.of<BarBloc>(context);
          return BlocBuilder<BlocEvent, BlocState>(
              bloc: barBloc,
              builder: (BuildContext context, BlocState barState) {
                if (barState is BarUpdated) {
                  // use fooState and barState to build UI
                }
              });
        }
      });
}

Or should instead I always go to the trouble of creating a FooBarBloc and combining both Foo and Bar state streams with e.g. Observable.combineLatest2(), along with a whole new set of FooBar event classes and FooBar state classes? Would both approaches (i.e. nested BlocBuilders and a new FooBarBloc) effectively amount to the same thing, outside of potential reusability of FooBarBloc?

Thanks for any comments/advice RE: above in particular and presumably quite common data-joining scenarios with BLoC in general much appreciated.

question

Most helpful comment

Hey @brent-williams 馃憢
Thanks for the positive feedback and for opening an issue!

Regarding your questions,

  1. That looks good to me 馃憤
  2. Nested BlocBuilders vs Composition of Blocs into a new Bloc is a case-by-case decision. Usually whichever is less awkward is the one I'd go with. If FooBarBloc doesn't make sense on it's own, then nesting BlocBuilders is perfectly fine. Alternatively, if FooBarBloc can be reused and makes sense as a standalone bloc, then I'd say go for it. I try to have one or more blocs per feature so if FooBarBloc corresponds to a separate feature then it would probably be good to create a new bloc with new states/events. Again, all of this is very high level and generic so it's hard to say for sure which is the right approach. If you're still unsure, it'd be awesome if you could share specifics about what FooBloc and BarBloc are in this case.

Let me know if that helps and great question 馃憤

All 5 comments

Hey @brent-williams 馃憢
Thanks for the positive feedback and for opening an issue!

Regarding your questions,

  1. That looks good to me 馃憤
  2. Nested BlocBuilders vs Composition of Blocs into a new Bloc is a case-by-case decision. Usually whichever is less awkward is the one I'd go with. If FooBarBloc doesn't make sense on it's own, then nesting BlocBuilders is perfectly fine. Alternatively, if FooBarBloc can be reused and makes sense as a standalone bloc, then I'd say go for it. I try to have one or more blocs per feature so if FooBarBloc corresponds to a separate feature then it would probably be good to create a new bloc with new states/events. Again, all of this is very high level and generic so it's hard to say for sure which is the right approach. If you're still unsure, it'd be awesome if you could share specifics about what FooBloc and BarBloc are in this case.

Let me know if that helps and great question 馃憤

Closing for now but feel free to comment with additional questions and I'm happy to continue the conversation 馃憤

@felangel Nested BlocBuilder doesn't honor condition .

My use case:

Player widget -> Show only when the player is playing
The Player Widget has play , pause, stop, title, progress bar, timer,

I don't want the player widget get redrawn completely for event change in timer, to update only the timer. How do I nest it with condition with single Bloc

@vjyanand the condition on BlocBuilder only comes into play when the bloc's state changes. There are many other reasons for BlocBuilder to rebuild such as if the parent widget rebuilds.

Have you taken a look at the timer tutorial? It includes how to add a condition to optimize for rebuilds towards the end of the actions section.

Hope that helps 馃憤

Yes, but nested blocbuilder doesn鈥檛 work as expected with condition

Was this page helpful?
0 / 5 - 0 ratings

Related issues

timtraversy picture timtraversy  路  3Comments

komapeb picture komapeb  路  3Comments

rsnider19 picture rsnider19  路  3Comments

RobPFarley picture RobPFarley  路  3Comments

shawnchan2014 picture shawnchan2014  路  3Comments