Skip to content

Instantly share code, notes, and snippets.

@stegrams
Last active June 7, 2020 23:40
Show Gist options
  • Save stegrams/8c81aa874330186a352a8bc0ad55ce7b to your computer and use it in GitHub Desktop.
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.
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