felangel / bloc

A predictable state management library that helps implement the BLoC design pattern
https://bloclibrary.dev
MIT License
11.79k stars 3.39k forks source link

chore(hydrated_bloc): usage questions #3647

Closed ffeliciodeveloper closed 1 year ago

ffeliciodeveloper commented 1 year ago

Description

Hello everybody!

I hope you are all well!

I already apologize before, in case I come to ask something silly, I'm still a beginner in development with Flutter.

I would like to know more details about the use of hydrated_bloc and if it would be useful for the case in which I have a certain challenge.

The case is as follows: We are currently developing an application that needs information from the logged in user at different times. We thought of using some internal storage process such as shared preferences (or other), and in each block that the authentication data was used (token, user id), we would have a usecase that would carry out the process of retrieving the authentication data. In another project we made this flow, but it really was a very verbose process to carry out.

In another project we used a session concept, where this type of internal storage was not available and its use was made with a singleton class that exposed the authentication data, but what was the problem with this approach? When the user fully closed the app, the singleton was cleared and ended up giving null authentication data when the user stops using the app.

A friend introduced me to the site bloclibrary.dev, and browsing it I ended up finding hydrated_bloc, and I believe that with it I could solve this case. In question what would it be? I would have a block responsible for carrying out the authentication processes and in this case, the hydrated_bloc would be used to store the authenticated user, then the questions would be the following:

1 - in another block that needed to use some information from the authentication data, would it be possible to use what is stored in the block that uses hydrated_bloc? 2 - would it be better to use another resource in this case? 3 - would there be a smarter way to do this?

Again, I apologize if I said anything wrong and thank you very much for your help.

nicelogic commented 1 year ago

I have the similar question. currently. I use the following way: a auth bloc to manager auth state(authstatus, access token, refresh token). inject a auth repository a user bloc listen auth bloc's state change

but from https://bloclibrary.dev/#/architecture?id=bloc-to-bloc-communication @felangel said this way is should be avoid ( it creates a dependency between two blocs.) and It is recommended to use "Connecting Blocs through Domain" or through Presentation

but i think this way will make repository too coupled with the business if every repository just support data query/mutation/subscription interface repository will simple and every bloc support all business logic this can make repository and bloc's respective responsibilities clearer such as: auth bloc support timer to refresh token instead auth_repository to do this work when user logout, the timer should be canceld. if the timer wokr do in auth repository, will make auth repository no longer a pure data provider

bloc is a business state manager. There is a dependency relationship between business and business itself So it should also be reasonable that there is a dependency relationship between blocs. Not according to the official documentation. it bothers me image

i realy don't want to move auth business logic to auth repository that will make auth repository no longer pure data repository i feel comfortable if all auth logic in auth bloc(hydrated), and other bloc use auth bloc's state(access token), and listen the auth bloc's state change(access token update). other bloc which need app auth state just get/listen auth bloc, needn't care about auth repository

if many bloc want's same state, could has common top level bloc to support shared state

hbali commented 1 year ago

@nicelogic hi!

connecting blocs with each other is a problem we had lot of times as well. exposing a bloc to another bloc is obviously bad, no arguing there. But usually you don't need the whole state of the bloc right? Usually a single variable is enough (or two). What we did as a solution is to create a simple streamcontroller and stream in the first bloc and the stream is injected into the second bloc via the constructor.

So as a quick example:

BlocState { 
 final int var1;
 final String var2;
 ...etc
}
Bloc1<BlocEvent, BlocState> {
     StreamController<int> _var1Controller = StreamController<int>();
     Stream<int> var1Stream = _var1Controller.stream;
}
Bloc2 {
  Bloc2(Stream<int> var1Stream) {
    var1Stream.listen(...event handling)
  }
}

This way there is no direct dependency since bloc2 doesn't know anything about bloc1. If more variables are needed in bloc2 then it's another problem in my opinion since the two blocs share too many responsibilities

felangel commented 1 year ago

Closing this for now but feel free to comment with additional thoughts/questions and I'm happy to continue the conversation 👍