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

Design - Handling multiple api calls in parrallel #508

Closed jregnier closed 5 years ago

jregnier commented 5 years ago

Hello Felix, first off great work with this package. I have a design question. I have a scenario where I want to show a details screen and to do so I need to make multiple api calls. So I dispatch a FetchDetailsEvent and I would like to make all the api calls in parallel. Also is there a way not to redraw everything every time? Basically, I just want to redraw small parts of the screen as the api call returns. Before I started to use the package I was doing this with a FutureBuilder.

bigworld12 commented 5 years ago

i assume you are calling your api in mapEventToState ? the great thing about mapEventToState is that it returns a stream, which means you can yield multiple times in the same call. e.g. -> await Api call 1 -> yield state containing api 1 result -> await API call 2 -> yield state containing api 2 result

but if you want to make them in parallel, you will have to dispatch an event in each thread

e.g. -> thread 1 ----> await Api call 1 ----> dispatch event saying that Api call 1 finished , and send the result along with it -> thread 2 ----> await Api call 2 ----> dispatch event saying that Api call 2 finished , and send the result along with it

bigworld12 commented 5 years ago

also if you are using the repository pattern alongside BLoC pattern, then you can make the api calls edit values in the repository, making the state just a notification to the UI better than carrying the actual data

jregnier commented 5 years ago

ya, the multiple yields in the mapEventToState method is the way I currently have it which works well but was hoping to only redraw the part of the screen that the API call represents. As for your second comment technically I could have the state as a notification then when building the UI in BlocBuilder I could use a FutureBuilder to call to the API method from the repo.

It seem that if I wanted to achieve this with the framework I would need 1 bloc per API I'm calling? Or is it possible or bad practice to have the BlocBuilder listen to an actual state class and not the base class? That way I could have multiple BlocBuilder only redrawing parts of the screen. Let me know if that's totally crazy lol

bigworld12 commented 5 years ago

@jregnier you can already do that with BlocBuilder, it has a condition property, which passes a previous state and a next state, from those 2 you can judge if you want to redraw that specific area or not. e.g. your UI has 5 changeable areas. -> put a BlocBuilder for each changable area -> preferably, only put BlocBuilders around the areas that actually need to be redrawn, also try not to nest BlocBuilders together -> put a condition on each BlocBuilder that specifies when to trigger redrawing that specific area. -> in your bloc state AND event you can have an enum that tells which area needs to be redrawn

enum UIArea {
    Area1, Area2, Area3, Area4, Area5
}

you can use that enum as the condition for bloc builders

And no, you don't need 1 bloc per API, you need : -> a single provider for all APIs from a single source, (e.g. a provider for actual data from the server, a provider for actual data from another server , a provider for mock test data that you manually created) -> one or more repositories per application, each repository can use one or more providers, (e.g. a repository for storing current user info, a repository for storing list of hotels, ...) -> one or more BLoCs for each logical flow that depends on a repository/provider (e.g. a BLoC for user Auth, a BLoC for drawing list of hotels, [which would only tell the list that its items changed, and the list gets the new items from the repository], ...)

you can check the amazing architecture documentation by @felangel here https://felangel.github.io/bloc/#/architecture , which has a very good explanation

felangel commented 5 years ago

Hi @jregnier 👋 Thanks for opening an issue!

@bigworld12 beat me to it and had awesome answers 💯 The only thing I want to add is the timer tutorial illustrates how to use BlocBuilder with a condition so you might want to check that out if you haven't already.

Closing for now but feel free to comment with any additional questions/concerns if you have them 👍

jregnier commented 5 years ago

@bigworld12 that's exactly what I was looking for thanks!! I remember reading about it but didn't put it together. 🥇