I'm reading in user-provided input (in this case a zip code) from a TextField
that I need to check against a database for validity. However, I need to make an asynchronous database query inside of the submit button's (a RaisedButton
in this case) onPressed: () {}
lambda function. In most programming languages, this is a fairly straightforward and simple task. The problem I'm running into in Flutter, however, is the fact that Future
objects returned from asynchronous database queries can only be consumed by FutureBuilder
objects which in turn only return Widget
objects. I simply need a String
returned that I can then use to either pass to a new route via a MaterialPageRoute
object, or display an error to the user without changing routes. Is there any way to do this with Flutter? Returning a Widget is useless to me as I don't want to create a new Widget for display. I am using Flutter 0.3.2 and Dart 2.0.0
As a simplified example of where I need to call the database query:
@override
Widget build(Buildcontext context) {
return new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Container(
padding: const EdgeInsets.all(16.0),
child: new TextField(
keyboardType: TextInputType.number,
controller: _controller,
decoration: new InputDecoration(
hintText: 'Zip Code',
),
onSubmitted: (string) {
return string;
},
),
),
new RaisedButton(
onPressed: () {
// use regex to test against user input
if (_controller.text != null && _controller.text.isNotEmpty) {
RegExp zipCodeRegExp = new RegExp(r"^(\d{5})$");
// if the user input validates...
if (zipCodeRegExp.hasMatch(_controller.text)) {
zipCode = _controller.text;
// need to perform database query here and return a string, not a Widget
} else {
// an else condition here
}
} else {
// an else condition here
}
}
}
),
],
);
}
Perhaps I'm not following the "mantra" of Flutter? I appreciate your consideration and input on this.
In Flutter, the FutureBuilder Widget is used to create widgets based on the latest snapshot of interaction with a Future. It is necessary for Future to be obtained earlier either through a change of state or change in dependencies.
You can calculate future value with compound interest using this formula: future value = present value x (1 + interest rate)n. To calculate future value with simple interest, use this formula: future value = present value x [1 + (interest rate x time)].
So the builder is properly rebuilt on changing the future if you trigger the change with setState. The problem is, the hasData and hasError aren't reset until the response is back. But we can use connectionState instead. You can refresh the widget by clicking on FlatButton.
FutureBuilder
is just a convenient helper to get the widget tree rebuilt when a Future completes.
You can use
funcThatReturnsFuture().then((result) {
print(result);
setState(() {
someVal = result;
})
})
or
Future funcThatMakesAsyncCall() async {
var result = await funcThatReturnsFuture();
print(result);
setState(() {
someVal = result;
})
}
The main limitation is that you can't return the value directly to the caller without a Future
, because there is no way to get back from async execution to sync execution.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With