I think is not possible to use async using @action.
When I use it Im getting the following error:
This works nice:
@observable
List<Location>locations = [];
@action
Future<List<Location>> fetchLocations(){
_apiClient.getLocations().then((x){
locations.addAll(x);
});
}
But this:
@action
Future<List<Location>> fetchLocations() async {
locations = await _apiClient.getLocations();
}
Generates an error:
[SEVERE] mobx_codegen|mobx_generator on lib/ui/location/state/locations.dart:
Could not make class "Locations" observable. Changes needed:
1. Remove async modifier from the method "fetchLocations"
I believe a good practice for MobX is to separate async code from your actions. E.g.:
// Changed List to ObservableList, see below for details
@observable
ObservableList<Location> locations = [];
void fetchLocations() async {
final locations = await _apiClient.getLocations();
addLocations(locations);
}
@action
addLocations(List<Location> newLocations) {
locations.addAll(newLocations);
}
Note:
@observable
List<Location> locations = [];
doesn't track any changes to the list length (.add(), .remove(), etc), except if it is assigned a new list every time you want to change it, like so: this.locations = this.locations + [a, b, c].
So it's easier to use ObservableList instead of List, which responds to any changes as you would expect.
Ok, Im new using mobx, I though that actions can be only called from UI, Can you explain your answer here please?
https://stackoverflow.com/questions/54735616/remove-async-modifier-from-the-method-fetchdata
Thanks!
I cant do
@observable
ObservableList<Location> locations = [];
Becase:
The list literal type 'List
Fixed:
@observable
ObservableList<Location> locations =ObservableList<Location> ();
Im reading the book "MobX quick start guide" where I have read the following snippet:
@action.bound
async search() {
try {
this.status = 'pending';
const result = await searchBooks(this.term);
runInAction(() => { this.totalCount = result.total; this.results
= result.items; this.status = 'completed';
});
} catch (e) {
runInAction(() => (this.status = 'failed'));
console.log(e);
}
}
How can we do this if we cant use async in actions?
You can wrap this.status = 'pending'; in the runInAction too and you will not need the @action.bound then.
I think this library is not ready for production, I tried to use it but ... Im having a lot of problems with the build_runner.
The current Dart SDK version is 2.1.0-dev.9.4.flutter-f9ebf21297.
If you would like to help you can raise an issue regarding your build_runner problems.
build_runner itself is sometimes buggy, but this is not part of MobX. You may have to run flutter packages pub run build_runner clean or rm -rf .dart_tool/
Most helpful comment
I believe a good practice for MobX is to separate async code from your actions. E.g.:
Note:
doesn't track any changes to the list length (
.add(),.remove(), etc), except if it is assigned a new list every time you want to change it, like so:this.locations = this.locations + [a, b, c].So it's easier to use
ObservableListinstead ofList, which responds to any changes as you would expect.