Bloc: Issue with common states between few blocs

Created on 15 Feb 2020  路  6Comments  路  Source: felangel/bloc

It's actually not a bug, but rather Bloc design issue. Too hard create some common state that could be used in few different bloc classes in current implementation of Bloc.

For example, my application have authorisation and access token could be expired in some moment, as result by expiration of token I should ask user to sign in again. So it means that each bloc that somehow related to network requests should have something like authorization error state. Should developer create new state for each state hierarchy or what solution should be used by developers in this case?

question

Most helpful comment

Hi @felangel . I have implemented sample that you asked for https://github.com/EgorLogachev/flutter_bloc_common_states_issue_sample. I have implemented two similar apps with the same UI and the same business logic, but the first one uses flutter_bloc, and the second one uses my solution. I have covered all cases that we were talking about and if you compare these applications, I hope you will understand. Especially pay attention to common_states.dart and connection_bloc.dart files in both apps.

All 6 comments

Hi @EgorLogachev 馃憢
Thanks for opening an issue!

I believe this is duplicate of https://github.com/felangel/bloc/issues/766. Check out https://github.com/felangel/bloc/issues/766#issuecomment-571811625 and let me know if that helps.

TL;DR your feature blocs should not care about access tokens since that's a networking layer detail. Instead of exposing that information to each bloc, I recommend having an onExpired callback in your httpClient which notifies your AuthenticationBloc to update its state.

final httpClient = HttpClient(onTokenExpired: () => _authenticationBloc.add(TokenExpired());

Then if you have a BlocBuilder at the top of your widget tree which handles rebuilding based on changes in AuthenticationState your lower level blocs should not care about AuthenticationState or token expiration.

Please let me know if that helps, thanks! 馃憤

@EgorLogachev can we close this issue?

Hi @felangel. Sorry, but I'm not sure that you understand what I mean. Issue is not only in handling of token expiration. It's just example.
Each bloc can generate as minimal 4 common states: loading progress, connection errors, authorization errors, other unexpected errors
and I think that some new common states could appear in process of development. And issue that bloc library doesn't have useful and flexible way to handle and manage that. Yes, I can create some bloc on top of widgets tree that will observe some repository property and handle some case. What should I to do if will appear some group of screens that should handle same state but with little different logic? And solution that you have provided in your comment above will not solve this problem, because I can't extend AuthenticationBloc just for few screens. Or should I somehow notify AuthorisationBloc to unsubscribe from repository and build-in other BlocListener with other bloc that extend AuthenticationBloc? Thanks for you solution, but I think that each bloc should have possibility generate common states without code duplication and complex solutions.

@EgorLogachev the bloc library has no opinion about how you model your state. If you want to have common base classes you can. Another option is to have mixins which you reuse. Ultimately your only limitation is the Dart language in terms of how you model state.

Regarding the AuthenticationBloc example, I鈥檓 not sure I understand why you would want extend AuthenticationBloc and have multiple different variants of AuthenticationBlocs in a single app.

Can you please provide a link to a sample app which illustrates the problems you鈥檙e having? It would be much easier to provide suggestions if there is a concrete use case. Thanks!

@felangel sorry for late reply I was busy. So about reusable mixins. Yes I thought about it but I don't prefer this solution. Average mobile app contains about 10 screens, so it is 10+ different bloc classes. Each bloc class should contains 4+ common states. I should implement 4+ interfaces/mixins for each hierarchy of states per each bloc in result. I'm not sure that it very flexible solution and I don't wanna manage all of that.

About solution with BlocListener and AuthBloc on top. So imagine mobile application that have call/chat feature. Application have contacts list in this app and each list item contains call/chat button. User could open contact details screen by click on list item. The screen contains buttons call/chat too. Business logic of buttons similar for both screens. When user click on call/chat button token expiration issue appear and user should re-login. And main idea that after re-login, chat/call action that was affected by token issue should be executed automatically again without user interaction.

About sample app. I hope that this weekend I'll have some free time, so I'll provide it later.

Hi @felangel . I have implemented sample that you asked for https://github.com/EgorLogachev/flutter_bloc_common_states_issue_sample. I have implemented two similar apps with the same UI and the same business logic, but the first one uses flutter_bloc, and the second one uses my solution. I have covered all cases that we were talking about and if you compare these applications, I hope you will understand. Especially pay attention to common_states.dart and connection_bloc.dart files in both apps.

Was this page helpful?
0 / 5 - 0 ratings