Open utterances-bot opened 4 years ago
"The MobX for Dart documentation also suggests using provider" can you please give the reference where they actually said this in documentation.
https://mobx.pub/guides/stores#using-providers-to-avoid-singletons
This is the same page I mentioned on that talks about the widget-store-service triad
https://mobx.pub/guides/stores#using-providers-to-avoid-singletons
This is the same page I mentioned on that talks about the widget-store-service triad
Thanks
No worries. I've updated the post with that link too since some may not have opened it from the previous paragraphs
Hi, I have question about tests, for example my store looks like:
abstract class _CategoryStoreBase with Store {
final ApiService _api;
final AsyncMemoizer _asyncMemorizer = AsyncMemoizer();
_CategoryStoreBase(this._api);
@observable
model.Category active;
@observable
ObservableFuture fetchCategoriesFuture;
@observable
ObservableList<model.Category> list = ObservableList<model.Category>();
@action
Future<void> fetch() async {
fetchCategoriesFuture = ObservableFuture(_asyncMemorizer.runOnce(() async {
await _api.fetchCategories().then((categories) {
print(categories); // <-- IMPORTANT
list.clear();
list.addAll(categories);
});
}));
}
}
Just like in yours example than I'm trying to write test for this code:
test('Fetch store list', () async {
.....
final store = CategoryStore(api);
await store.fetch();
print(store.list); // []
expect(store.list.isNotEmpty, true); // here it's false (list is empty)
});
but after test crashed it's prints not empty list (see IMPORTANT line) seems like it doesn't wait for fetch(). Whats wrong?
After that I rewrote my code:
@action
Future<dynamic> fetch() async {
return _asyncMemorizer.runOnce(() async {
var categories = await _api.fetchCategories();
list.addAll(categories);
return categories;
});
}
and test:
final store = CategoryStore(api);
var categories = await store.fetch();
expect(categories.isNotEmpty, true);
expect(store.list.isNotEmpty, true);
now It works, but how to get work previous example? and why we should use fetchCategoriesFuture
?
Hmm I double checked my examples and don't see where I've used the then
callback that's similar to how you work with JavaScript's promises. I believe your first one fails because you don't actually await for the fetching to be done within the fetch
method.
In your first example you have
@action
Future<void> fetch() async {
fetchCategoriesFuture = ObservableFuture(_asyncMemorizer.runOnce(() async {
await _api.fetchCategories().then((categories) {
print(categories); // <-- IMPORTANT
list.clear();
list.addAll(categories);
});
}));
}
fetch
here is expected to return a Future
(i.e. do some asynchronous computation) but it only does a synchronous operation of setting the value of fetchCategoriesFuture
. What should fix it is if you return fetchCategoriesFuture
within the code for fetch
.
Regarding why you would use fetchCategoriesFuture
, I assume you mean why you would use an ObservableFuture
(which is the object type). This is so you can use MobX's Observer
widget (or other reactions) to respond to status changes. This is similar to how you would pass a Future
to a FutureBuilder
. Using an ObservableFuture
may not be necessary but allows you to be consistent in using MobX's APIs to respond to state changes
Thanks for your answer. So, with MobX I should use ObservableFuture instead of FutureBuilder or it's possible to combine them?
No at I said it may not be necessary. It's up to you
Managing UI state in Flutter with MobX and provider - Dissecting a Hacker News app
https://dexterx.dev/managing-ui-state-in-flutter-with-mobx-and-provider/