So, I'm Using your Bloc library, Awesome by the way 馃檹馃徎, now i have some issues i would love to get your help with.. I have a Bloc in a screen that dispatches events and reacts to states just fine when i create the Bloc in that screen.. but then i wanted to access the bloc and dispatch an event from another screen.. but when i create the bloc in the other screen no changes in the first screen.. i figured it's because it's a different instance of the bloc , so my question is do i convert the bloc to a singleton to get a consistant instance or is there a better approach to my situation?
Thanks 鈽猴笍
Thank you, That pretty much explained it all :)
Ok, Facing one more problem that's not in the linked blog 馃し鈥嶁檪 馃槀
Related to the instance question above, I get that a Global Bloc Provider passes the BLOC down to all parts of the widget tree, but what if i need to use the bloc outside the widget tree? say in an Error Handling utility im working on?
any thoughts?
Thanks! 馃槃
@micwaziz if you want to log errors you can use BlocDelegate
which exposes an onError
where you can easily do just that.
As for handling error with regards to UI, you should yield error states from your bloc, listen to those states using a BlocListener
and handle them accordingly(eg: maybe show a proper snackbar with a descriptive error message).
I don't want to get bloc errors, i have a seperate bloc which recieves errors from all over the app (eg. Api call errors ) Therefore there's no context to pass and therefore not the same instance.. do you get what i mean?
I don't see why you would create a dedicated bloc for errors. I personally don't feel like that's good architecture since errors can easily be dealt with inside bloc/bloc delegate in a more natural way.
@micwaziz I agree with @RollyPeres. Having an ErrorBloc is a bit of an anti-pattern because instead of having independent blocs which handle their own errors you're funneling all errors through a single bloc. I would love to get some more context regarding why you decided to go with this approach.
I designed my backend to give different codes based on the error I'm facing (Api related), so i want a seperate entity in my flutter app to get the error, decode to the proper message, and deliver the right message to the current contex through a scaffold or something similar.. i can see your concerns regarding the pattern, but what would you rather suggest instead? i really am up for advise and do appreciate both your helps :D
@RollyPeres @felangel
@micwaziz I believe a clean way of approaching it would be to return proper httpstatuscodes from your api + optional custom error code and/or detailed error message. You then check the status and/or custom error codes in your client side repository layer and you then throw app specific errors/exceptions, which you then catch in your bloc and yield proper error states. You could also rethrow these errors in blocs, if you wanna handle your error logging in onError
from BlocDelegate
.
To further help you, I'll walk you through a quick example, starting with the API: your user made a request using some username+password combination, one of which is wrong; you could then return a httpstatuscode of 401 unauthorized(you could also add custom error code for example to know whether it was the username or password, if that's something you're interested to know on the client side, but we gonna keep it simple here), check this status code on client side and throw for example a WrongCredentialsException
; in your bloc you can handle this exception and maybe yield AuthFailure
state which contains an errorMessage
of Your username or password was invalid, please try again.
, which will be rendered on your UI.
Hope that helps!
That's exactly what i'm trying to do! , but what i'm asking about is the repository layer doesn't have a context so i will need to create an instance of the authentication bloc in it, right? but i already have a global instance of the Authentication bloc which i instantiated with a bloc provider parenting the material app, so now i have two instances of the Authentication Bloc, one in the widget tree and one in the repository layer.. am i misunderstanding something?
Thanks!
@micwaziz your layers would be something like: AuthRepository(Data layer) -> AuthBloc(BLoC layer) -> AuthScreen(Presentation layer aka UI layer)
. Basically you're going to consume AuthRepository
inside AuthBloc
, and the AuthBloc
on your UI using either one of BlocBuilder
, BlocListener
or BlocConsumer
. You would probably also need to fetch the bloc to add events on it. The context
should not leave the UI, so passing it around the app in layers other than UI is really inadvisable.
You can check out https://bloclibrary.dev/#/architecture for even more details and quick examples of what a solid architecture should look like.
Thank you, i will give it a try!
Most helpful comment
Thank you, That pretty much explained it all :)