Last active
June 7, 2020 23:40
-
-
Save stegrams/8c81aa874330186a352a8bc0ad55ce7b to your computer and use it in GitHub Desktop.
When setState called after await completion, usually there is not state to update. This an attempt to amend the issue.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'dart:async'; | |
import 'dart:convert'; | |
import 'dart:math'; | |
import 'dart:html'; | |
import 'package:flutter/material.dart'; | |
Future<String> fetchHttpRes(int id) async { | |
final f1 = 'first_name', f2 = 'last_name', timeoutSec = 300; | |
final url = 'https://reqres.in/api/users/$id?delay=$id'; | |
HttpRequest request = await HttpRequest.request( | |
url, | |
mimeType: 'application/json', | |
).timeout( | |
Duration(seconds: timeoutSec), | |
onTimeout: () => throw Exception( | |
'Server unresponsive after $timeoutSec seconds', | |
), | |
); | |
if (request.status != 200) | |
throw Exception( | |
'${request.statusText} Status: ${request.status}.', | |
); | |
Map<String, dynamic> result = json.decode(request.responseText); | |
if (result.isEmpty) | |
throw Exception( | |
'User id "$id" not found!', | |
); | |
String val1 = result['data'][f1], val2 = result['data'][f2]; | |
return 'id: $id, value: $val1 $val2'; | |
} | |
void main() => runApp(MyApp()); | |
class MyApp extends StatefulWidget { | |
@override | |
_MyAppState createState() => _MyAppState(); | |
} | |
class _MyAppState extends State<MyApp> { | |
Future<String> futureHttpRes; | |
bool updating; | |
@override | |
void initState() { | |
super.initState(); | |
updateHttpRes(); | |
} | |
Future<void> updateHttpRes() async { | |
setState(() => updating = true); | |
int userId = Random().nextInt(12) + 1; | |
try { | |
await (futureHttpRes = fetchHttpRes(userId)); | |
} finally { | |
// Yes I know! Another setState after await. | |
// But this, for some reason, doesn't break. | |
setState(() => updating = false); | |
} | |
} | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
title: 'Fetch Data Example', | |
home: Scaffold( | |
appBar: AppBar( | |
title: Text('Fetch Data Example'), | |
), | |
body: Center( | |
child: FutureBuilder<String>( | |
future: futureHttpRes, | |
builder: (context, snapshot) { | |
if (snapshot.connectionState == ConnectionState.waiting) { | |
return CircularProgressIndicator(); | |
} | |
String msg; | |
if (snapshot.hasError) { | |
if (snapshot.error is ProgressEvent) { | |
ProgressEvent pe = snapshot.error as ProgressEvent; | |
msg = 'ProgressEvent type: ${pe.type}'; | |
} else { | |
msg = snapshot.error.toString(); | |
} | |
} else { | |
msg = snapshot.data; | |
} | |
return Text(msg, style: TextStyle(fontSize: 30)); | |
}, | |
), | |
), | |
floatingActionButton: FloatingActionButton( | |
onPressed: updating ? null : updateHttpRes, | |
backgroundColor: updating ? Colors.grey : Colors.blue, | |
disabledElevation: 0, | |
child: Icon(updating ? Icons.hourglass_empty : Icons.refresh), | |
), | |
), | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment