An alternative to flutter's built-in State class made specifically to deal with async http requests.
Add the package to your pubspec.yaml:
dependencies:
request_state: ^0.0.1Using RequestState is really simple. Assume you have a StatefulWidget called SomeWidget that you want to work with http requests.
import 'package:flutter/material.dart';
class SomeWidget extends StatefulWidget {
@override
_SomeWidgetState createState() => _SomeWidgetState();
}
class _SomeWidgetState extends State<SomeWidget> {
@override
Widget build(BuildContext context) {
return Container();
}
}To allow this widget to use RequestState you:
- Import
RequestState:
import 'package:request_state/request_state.dart';- Exchange
State<SomeWidget>forRequestState<SomeWidget>
import 'package:flutter/material.dart';
import 'package:request_state/request_state.dart';
class SomeWidget extends StatefulWidget {
@override
_SomeWidgetState createState() => _SomeWidgetState();
}
class _SomeWidgetState extends RequestState<SomeWidget> {
@override
Widget build(BuildContext context) {
return Container();
}
}Then, you can remove the build() method override, and instead you must override idleBody(), waitingForResponseBody() and responseReceivedBody():
import 'package:flutter/material.dart';
import 'package:request_state/request_state.dart';
class SomeWidget extends StatefulWidget {
@override
_SomeWidgetState createState() => _SomeWidgetState();
}
class _SomeWidgetState extends RequestState<SomeWidget> {
@override
Widget idleBody(BuildContext context) {
return Container();
}
@override
Widget waitingForResponseBody(BuildContext context) {
return CircularProgressIndicator();
}
@override
Widget receivedResponseBody(BuildContext context) {
return Text("Response Received");
}
}These three methods define what child your widget should show at different stages of the request. idleBody()
is shown before a request has been sent for the first time, waitingForResponseBody() is shown once a request
has been sent but no response has been received yet, and receivedResponseBody() is shown when a response has
successfully been received.
You may also optionally override requestFailedBody() to define what is shown when sending the request fails.
By default this uses the widget provided to idleBody().
import 'package:flutter/material.dart';
import 'package:request_state/request_state.dart';
class SomeWidget extends StatefulWidget {
@override
_SomeWidgetState createState() => _SomeWidgetState();
}
class _SomeWidgetState extends RequestState<SomeWidget> {
@override
Widget idleBody(BuildContext context) {
return Container();
}
@override
Widget waitingForResponseBody(BuildContext context) {
return CircularProgressIndicator();
}
@override
Widget receivedResponseBody(BuildContext context) {
return Text("Response Received");
}
@override
Widget requestFailedBody(BuildContext context) {
return Text("Sending Request Failed");
}
}All four of these methods work the way you are used to with normal State's build() method.
To send a request you use the build-in sendRequest() method, passing in the URL to send the request to:
@override
Widget idleBody(BuildContext context) {
return RaisedButton(
child: Text("Send Request"),
onPressed: () {
sendRequest("https://my-api-url.com");
}
);
}This will send a GET request to https://my-api-url.com, showing waitingForResponseBody() whilst waiting
for a response from the API, and then show receivedResponse()Body when a response is received. Alternatively,
if sending the request fails, it will show the value of requestFailedBody().
You may optionally also specify the type of the request (only GET or POST supported as of version 0.0.1) by
passing a value of the RequestType enum to named type parameter (GET by default), a body for the request,
a Map<String, dynamic> passed to the named body parameter.
If you would like to fire a callback when a response is successfully received, you may pass a callback to the
onReceived argument of the sendRequest() method. The callback should have a void return type and provides
you with a Response object (from the http package) containing the received response.
@override
Widget idleBody(BuildContext context) {
return RaisedButton(
child: Text("Send Request"),
onPressed: () {
sendRequest("https://my-api-url.com", onReceived: (response) {
print("Response successfully received. The body of the response is: ${response.body}");
});
}
);
}Similarly, if you would like to fire a callback when sending a request is unsuccessful, you may pass it to the
onError argument of the sendRequest() method. Like onReceived, this should also have a void return type,
and provides you with the Exception object that was thrown.
@override
Widget idleBody(BuildContext context) {
return RaisedButton(
child: Text("Send Request"),
onPressed: () {
sendRequest("https://my-api-url.com", onError: (error) {
print("Sending request failed. The error is: $error");
});
}
);
}If you encounter a bug or have a suggestion, please open an issue for it on GitHub. Feel free to fork the repo and submit PRs on the original one. All suggestions and contributions are welcome.