With a Swift background, Flutter+Dart require a different thought-process. Future<T> is associated with async calls and it could be hard to re-route your brain in a one go. In this article I am sharing my experience on how the mindflow when dealing with Future<T> using SharePreferences as an example, from start to a 1-liner in 6 steps.
1. Direct mindflow:
This is how a method looks like with the consideration of existing of Future<T>, it doesn’t work since SharedPreferences.getInstance() returns Future<SharedPreferences> instead of SharedPreferences.
static int getCount(){
// This will return Future<SharedPreferences>, unwarp is needed.
final preferences = SharedPreferences.getInstance();
// Future<SharedPreferences> causes error
// because SharedPreferences has .getInt()
// but Future<SharedPreferences> does not have .getInt()
final value = preferences.getInt("attributeName");
return value;
}
2. Fix the Future!
To handle Future<SharedPreferences>, add async and await. But the value can be null!
// async is needed to use the keyword await
// async also require Future<int> instead of int
static Future<int> getCount() async {
// Keyword await "unwarp" Future<SharedPreferences> to SharedPreferences
final preferences = await SharedPreferences.getInstance();
// .getInt() works normally now,
// but null can be return if "attributeName" does not have a value
final value = preferences.getInt("attributeName");
return value;
}
3. Fix the null value!
Change the final to var for value to be validated:
// async is needed to use the keyword await
static Future<int> getCount() async {
// Good now
final preferences = await SharedPreferences.getInstance();
// Change final to var so value can be validated
var value = preferences.getInt("attributeName");
// Validating value
if (value == null){
value = 0;
}
return value;
}
4. Shorthand for if …
if … could be a bit blocky, we could replace it with (condition) ? (true) : (false):
static Future<int> getCount() async {
// Shortent this too
final pref = await SharedPreferences.getInstance();
// Replace if with (condition) ? (true) : (false)
var value = pref.getInt("attributeName") == null ? 0 : pref.getInt("attributeName");
return value;
}
5. Remove more
Future<T> can be stacked with (await Future<T>) to get T within the async method.
static Future<int> getCount() async {
// Remove this line too
// Replace it with (await Future<SharedPreferences>) to get SharedPreferences
var value = (await SharedPreferences.getInstance()).getInt("attributeName") == null ? 0 : (await SharedPreferences.getInstance()).getInt("attributeName");
return value;
}
6. One-liner!
1-liner, just return the value :
static Future<int> getCount() async {
return (await SharedPreferences.getInstance()).getInt("attributeName") == null ? 0 : (await SharedPreferences.getInstance()).getInt("attributeName");
}