Reputation: 23
I am trying to learn and work with APIs, I am using the Tiingo Stock API to get stock info. My current app is:
class _StockAppState extends State<StockApp> {
String out = "Enter Ticker and press Submit";
Map<String,String> headers = {
'Content-Type': 'application/json',
'Authorization' : <API KEY REMOVED>
};
void getPrice(String tick) async {
if(tick == ""){
out = "Enter Ticker and press Submit";
}else{
Response rep = await get('https://api.tiingo.com/tiingo/daily/$tick/prices', headers: headers);
if(rep.statusCode == 200){
List data = json.decode(rep.body);
Map dataS = data[0];
out = "Price: ${dataS['close']}";
}else{
out = "Error";
}
}
}
@override
void initState() {
super.initState();
}
TextEditingController ticker = new TextEditingController();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Stock App'),),
body: Column(
children: <Widget>[
TextField(
controller: ticker,
textAlign: TextAlign.left,
decoration: InputDecoration(
border: InputBorder.none,
hintText: 'Enter Ticker',
hintStyle: TextStyle(color: Colors.grey),
),
),
FlatButton(
onPressed: () async {
FocusScope.of(context).unfocus();
setState(() {
getPrice(ticker.text);
});
},
child: Text('Submit')
),
Text(out),
],
),
);
}
}
So, basically, when you enter a ticker and press submit, the app will change the "out" string var to display the stock price. But for the app to update, I am having to press submit twice.
Could anyone help?
P.S.: I have removed my API key for security reasons.
Upvotes: 0
Views: 702
Reputation: 4763
It is because you have async method in your setState
method.
The setState
method will be called synchronously.
So here problem is when setState
is performed and frame get refreshed your data from api has not arrived yet and it showing you the old data. When you again click the button your out
variable have new data (from your first click) which will be shown on the screen and API will be called again.
To solve your problem
FlatButton(
onPressed: () async {
FocusScope.of(context).unfocus();
await getPrice(ticker.text);
setState(() {
});
},
child: Text('Submit')
),
So call the setState
method after API call is completed.
To know more about async/await watch this video : https://www.youtube.com/watch?v=SmTCmDMi4BY
Upvotes: 1