Closed ftognetto closed 5 years ago
Hi @quantosapplications π Thanks for opening an issue!
Regarding your question, I think you're on the right path. The repositories should ideally interface with your data providers and expose streams of models that the blocs can consume. In your case, you can probably expose a posts
stream in the repository which the PostBloc
subscribes to and reacts to. Then whenever you have any features that need access to the posts, you would simply use the PostBloc
. If you want to modify posts, you can have other blocs that interface with the PostRepository
calling methods like addPost
, updatePost
etc...
This should scale nicely because you'll have a unidirectional data flow (posts will always flow down from the data-provider, to the repository, to the bloc, and to the UI).
You can use RepositoryProvider
to provide a single instance of your repository to your application and then consume the repository when creating your blocs via BlocProvider
BlocProvider(
builder: (context) => MyBloc(repository: RepositoryProvider.of<MyRepository>(context)),
child: MyChild(),
),
Regarding having different kinds of post lists, you can have different post blocs which listen to the root postBloc's stream and filter/modify the posts similarly to the FilteredTodosBloc in the Todos Example.
Hope that helps and I'm more than happy to answer any questions you have as you go on gitter as well as do some live coding sessions to work through obstacles π
hi @felangel thank you!
Yes, I was reading this https://medium.com/flutter-community/whats-new-in-flutter-bloc-0-19-0-bf58a7154661 you are the best!! π― π₯
And yes I am filtering different lists of posts using the same implementation you were using in the todo example.
The only thing I cannot afford with this approach is to get exactly the posts I need.
For example in the recent posts feed bloc, for retrieving new posts, I would dispatch a FetchRecentPosts event which would call
await postRepository.getMostRecent( page: 1, limit: 20 )
and get back (from repo to bloc) a list of integers that represent the id of the objects while the repository would update it's internal post list adding the new posts.
Then always in the bloc I would listen to the post stream in the repository and filter them accordingly with the list of ids that I retrieved before.
But the repository is emitting the new list before I can afford the ids list.
Future<List<int>> getAllPosts({int start, int limit}) async {
/// fetching new posts from api
final Response response = await call(api.getAll(start, limit));
final List<Post> posts = response.data.map<Post>((json) => Post.fromJson(json)).toList();
/// let stream emit a new list of post with the new ones
_posts$.sink.add([...oldPosts, ...posts]);
/// return the list of ids so who is calling knows which posts has been fetched
return posts.map((p) => p.id).toList();
}
Without doing all this I can simply reduce the repository list stream in the recent bloc by sorting posts with it's creation date on listening (like the filteredTodosBloc).
But this will lead to some strange behavior: In the recent list, for example, the first time I open it (and while the bloc is fetching recent posts for the first time) I would find in the ListView many posts that I fetched somewhere else in the app.
@ftognetto Hi Fabrizio!, I am really interested in how you solved this problem as I am dealing with the same exact one. Would you mind to share your experience? ππΌ
Hi @raulmabe I would not be rude to this library which is great but I am currently using another library of state management π Anyway the concepts are similar and I ended up solving this feature by having an api from the backend that gives the ids of the posts you liked, and store them in a place where you can access from the whole app. Then when you like a post you can add the id there and when you load the post in another page you know yet if you liked that post or not. Hope this can help!
Looking for clarification if anyone knows thank you.
Question: If multiple blocs have open stream listeners on the same repository, does that cause the application to open multiple streams to the db? Take Firebase for ex.
Follow Up: If so, that would be inefficient. And so what is the appropriate way to have a header bloc open a stream listener, and then action cubits / blocs depend on the header bloc for the models / state.
In other words, what is the pattern for a cubit or bloc to subscribe to a stream of data coming from another bloc.
Or am i wrong to want to do this, and each cubit regardless of function should open its own stream listener directly with the repository?
Hi @felangel ! Hope you're doing well.
I am building a production app in flutter using your library, so thank you :)
Since it's a social network app for me it's important to share many information across screen in a reactive way.
A simple example can be the number of likes or comments of a post, that must be synchronized across different screen (for example I have two feed pages one with last posts and one with most popular).
I managed this by providing a Posts bloc at the top of the app that is maintaining an updated map of posts, but this is becoming hard to maintain because I have always to remember to update this bloc from other blocs (when fetching new or most popular posts in the relative blocs or when updating one with a comment or a like).
This is the bloc I'm using:
posts_state.dart
posts_event.dart
posts_bloc.dart
So other blocs (for example, RecentsBloc which control the last posts feed) can update this one by calling
recents_bloc.dart
And Widgets (like the post comment count widget) can listen to PostsBloc change, so they can update themselves.
I found this solution working but now I'm thinking that it will not be scalable anymore.
So I started thinking that the repository layer, which is the only gateway for blocs to get data, should manage this and pass down to the blocs layer always updated data. Every repository must become singleton and expose a stream with an updated list of data which blocs can use by reducing what they need.
PostRepository.dart
I'm having some difficulties managing different kind of post lists with this approach, but do you think this could lead to a clean architecture?
Thank you,
Fabrizio