I have a flutter app, which fetches a list of products from the server (product are related to the user, so the list doesn't change that much) so I'm saving the product lists locally. I'm using moor as a local database inside the application. when the user opens the products list page:
- I get the latest product creation date.
- Request data created after that date from the server async.
- I open a stream from the database to load the local data.
- When the the server response arrives with new data, I save it to the database, then the database stream will provide that data.
the code:
Stream<List<Product>> getAllProducts() async* {
this
.fetchProductsOnline() // request data from server
.then((value) => this.insertMultipleProducts(value)); // then save the received data locally
yield* getLocalProductsList(); // meanwhile get the local data, and listen to new changes.
}
then inside my BLoC I have to listen to that stream of data, and then emit states containing the data. but I don't seem to find the best/proper way to do that.
what I tried:
yield the stream of data after mapping it, and wrapping its items inside the state:
Stream<ProductState> mapProductListPageOpenedEventToState() async* { yield ProductListLoading(); inProgress(); // enters the ui into a progress state yield* this .productRepository .getAllProducts() .map((event) => ProductListLoadedSuccess(event)); await outProgress(); // exists the ui from the progress state }
The problems I faced here are: - the code right under the stream yield, never gets executed (idk why). - it only work once, means if I exit that page and reopen it (trigger the load product even again), nothing would happen (no state change, no event triggered).
listen to the stream of data, and use the emit() method to emit new states.
Stream<ProductState> mapProductListPageOpenedEventToState() async* { yield ProductListLoading(); inProgress(); // enters the ui into a progress state this.productRepository.getAllProducts().listen((event) { if (event.isNotEmpty) { emit(ProductListLoadedSuccess(event)); outProgress(); } }); }
this approach worked properly, I achieved what I wanted, but the docs say that the emit() method, should be used for test purposes only, and that states from bloc should be yield only.
I'd appreciate any other solution that satisfies my needs, and that doesn't break any rules set by the docs.