### Perform an HTTP request Source: https://pub.dev/packages/dio/versions/5.4.3 Example of using the request method to send data with specific options. ```dart final response = await dio.request( '/test', data: {'id': 12, 'name': 'dio'}, options: Options(method: 'GET'), ); ``` -------------------------------- ### Perform a GET request with Dio Source: https://pub.dev/packages/dio/versions/5.4.3/example Basic implementation of a GET request using the Dio client. Requires the dio package to be imported. ```dart import 'package:dio/dio.dart'; /// More examples see https://github.com/cfug/dio/blob/main/example void main() async { final dio = Dio(); final response = await dio.get('https://pub.dev'); print(response.data); } ``` -------------------------------- ### Perform GET requests with query parameters Source: https://pub.dev/packages/dio/versions/5.4.3 Demonstrates two ways to pass query parameters: directly in the URL string or via the queryParameters map. ```dart import 'package:dio/dio.dart'; final dio = Dio(); void request() async { Response response; response = await dio.get('/test?id=12&name=dio'); print(response.data.toString()); // The below request is the same as above. response = await dio.get( '/test', queryParameters: {'id': 12, 'name': 'dio'}, ); print(response.data.toString()); } ``` -------------------------------- ### Handle DioException errors Source: https://pub.dev/packages/dio/versions/5.4.3 Use a try-catch block to handle DioException. Inspect the response property to access server-side error details or the requestOptions for client-side setup errors. ```dart try { // 404 await dio.get('https://api.pub.dev/not-exist'); } on DioException catch (e) { // The request was made and the server responded with a status code // that falls out of the range of 2xx and is also not 304. if (e.response != null) { print(e.response.data) print(e.response.headers) print(e.response.requestOptions) } else { // Something happened in setting up or sending the request that triggered an Error print(e.requestOptions) print(e.message) } } ``` -------------------------------- ### Initialize Dio instance Source: https://pub.dev/packages/dio/versions/5.4.3 Demonstrates creating a Dio instance with default settings or a custom BaseOptions object. ```dart final dio = Dio(); // With default `Options`. void configureDio() { // Set default configs dio.options.baseUrl = 'https://api.pub.dev'; dio.options.connectTimeout = Duration(seconds: 5); dio.options.receiveTimeout = Duration(seconds: 3); // Or create `Dio` with a `BaseOptions` instance. final options = BaseOptions( baseUrl: 'https://api.pub.dev', connectTimeout: Duration(seconds: 5), receiveTimeout: Duration(seconds: 3), ); final anotherDio = Dio(options); } ``` -------------------------------- ### Dio() Constructor Source: https://pub.dev/packages/dio/versions/5.4.3 Initializes a new Dio instance, optionally accepting a BaseOptions object to configure default settings like baseUrl and timeouts. ```APIDOC ## Dio Constructor ### Description Creates a new instance of the Dio client. It is recommended to use a singleton instance to manage configurations consistently. ### Parameters - **options** (BaseOptions) - Optional - Configuration object containing baseUrl, connectTimeout, and receiveTimeout. ``` -------------------------------- ### Configure proxy for IOHttpClientAdapter Source: https://pub.dev/packages/dio/versions/5.4.3 Use the createHttpClient callback to configure a proxy for native platform requests. ```dart import 'package:dio/io.dart'; void initAdapter() { dio.httpClientAdapter = IOHttpClientAdapter( createHttpClient: () { final client = HttpClient(); // Config the client. client.findProxy = (uri) { // Forward all request to proxy "localhost:8888". // Be aware, the proxy should went through you running device, // not the host platform. return 'PROXY localhost:8888'; }; // You can also create a new HttpClient for Dio instead of returning, // but a client must being returned here. return client; }, ); } ``` -------------------------------- ### POST /info (application/x-www-form-urlencoded) Source: https://pub.dev/packages/dio/versions/5.4.3 Demonstrates how to send data in the application/x-www-form-urlencoded format using the Dio client. ```APIDOC ## POST /info ### Description Sends data to the /info endpoint using the application/x-www-form-urlencoded content type. ### Method POST ### Endpoint /info ### Request Body - **id** (int) - Required - The identifier to be sent in the form data. ### Request Example { "id": 5 } ``` -------------------------------- ### Implement Custom Dio Client Source: https://pub.dev/packages/dio/versions/5.4.3 Use DioMixin to implement a custom Dio client. ```dart class MyDio with DioMixin implements Dio { // ... } ``` -------------------------------- ### Configure LogInterceptor Source: https://pub.dev/packages/dio/versions/5.4.3 Apply LogInterceptor to automatically log network activity. Ensure it is the last interceptor added to capture final states. ```dart dio.interceptors.add(LogInterceptor(responseBody: false)); // Do not output responses body. ``` ```dart dio.interceptors.add( LogInterceptor( logPrint: (o) => debugPrint(o.toString()), ), ); ``` -------------------------------- ### Configure platform-specific HttpClientAdapter Source: https://pub.dev/packages/dio/versions/5.4.3 Explicitly set the adapter for Web or native platforms using the appropriate import. ```dart import 'package:dio/browser.dart'; // ... dio.httpClientAdapter = BrowserHttpClientAdapter(); ``` ```dart import 'package:dio/io.dart'; // ... dio.httpClientAdapter = IOHttpClientAdapter(); ``` -------------------------------- ### Download a file Source: https://pub.dev/packages/dio/versions/5.4.3 Downloads a file from a URL and saves it to a local path. ```dart response = await dio.download( 'https://pub.dev/', (await getTemporaryDirectory()).path + 'pub.html', ); ``` -------------------------------- ### request(path, ...) Source: https://pub.dev/packages/dio/versions/5.4.3 The core method for performing HTTP requests with the Dio instance. ```APIDOC ## request(path, ...) ### Description Performs an HTTP request to the specified path. ### Parameters - **path** (String) - Required - The endpoint path. - **data** (Object) - Optional - The request body. - **queryParameters** (Map) - Optional - Query parameters for the request. - **cancelToken** (CancelToken) - Optional - Token to cancel the request. - **options** (Options) - Optional - Request-specific options such as the HTTP method. - **onSendProgress** (ProgressCallback) - Optional - Callback for upload progress. - **onReceiveProgress** (ProgressCallback) - Optional - Callback for download progress. ### Response - **Future>** - A future that resolves to the response object. ``` -------------------------------- ### Add dependency via Dart CLI Source: https://pub.dev/packages/dio/versions/5.4.3/install Use this command in your terminal to add the package to your project. ```bash $ dart pub add dio ``` -------------------------------- ### Upload multiple files using FormData Source: https://pub.dev/packages/dio/versions/5.4.3 Demonstrates how to include single or multiple files in a FormData request. ```dart final formData = FormData.fromMap({ 'name': 'dio', 'date': DateTime.now().toIso8601String(), 'file': await MultipartFile.fromFile('./text.txt', filename: 'upload.txt'), 'files': [ await MultipartFile.fromFile('./text1.txt', filename: 'text1.txt'), await MultipartFile.fromFile('./text2.txt', filename: 'text2.txt'), ] }); final response = await dio.post('/info', data: formData); ``` -------------------------------- ### Define Dio Request Options Source: https://pub.dev/packages/dio/versions/5.4.3 The Options class defines the structure for HTTP request configuration. Use these fields to customize individual request behavior. ```dart /// The HTTP request method. String method; /// Timeout when sending data. /// /// Throws the [DioException] with /// [DioExceptionType.sendTimeout] type when timed out. /// /// `null` or `Duration.zero` means no timeout limit. Duration? sendTimeout; /// Timeout when receiving data. /// /// The timeout represents: /// - a timeout before the connection is established /// and the first received response bytes. /// - the duration during data transfer of each byte event, /// rather than the total duration of the receiving. /// /// Throws the [DioException] with /// [DioExceptionType.receiveTimeout] type when timed out. /// /// `null` or `Duration.zero` means no timeout limit. Duration? receiveTimeout; /// Custom field that you can retrieve it later in [Interceptor], /// [Transformer] and the [Response.requestOptions] object. Map? extra; /// HTTP request headers. /// /// The keys of the header are case-insensitive, /// e.g.: `content-type` and `Content-Type` will be treated as the same key. Map? headers; /// Whether the case of header keys should be preserved. /// /// Defaults to false. /// /// This option WILL NOT take effect on these circumstances: /// - XHR ([HttpRequest]) does not support handling this explicitly. /// - The HTTP/2 standard only supports lowercase header keys. bool? preserveHeaderCase; /// The type of data that [Dio] handles with options. /// /// The default value is [ResponseType.json]. /// [Dio] will parse response string to JSON object automatically /// when the content-type of response is [Headers.jsonContentType]. /// /// See also: /// - `plain` if you want to receive the data as `String`. /// - `bytes` if you want to receive the data as the complete bytes. /// - `stream` if you want to receive the data as streamed binary bytes. ResponseType? responseType; /// The request content-type. /// /// The default `content-type` for requests will be implied by the /// [ImplyContentTypeInterceptor] according to the type of the request payload. /// The interceptor can be removed by /// [Interceptors.removeImplyContentTypeInterceptor]. String? contentType; /// Defines whether the request is considered to be successful /// with the given status code. /// The request will be treated as succeed if the callback returns true. ValidateStatus? validateStatus; /// Whether to retrieve the data if status code indicates a failed request. /// /// Defaults to true. bool? receiveDataWhenStatusError; /// See [HttpClientRequest.followRedirects]. /// /// Defaults to true. bool? followRedirects; /// The maximum number of redirects when [followRedirects] is `true`. /// [RedirectException] will be thrown if redirects exceeded the limit. /// /// Defaults to 5. int? maxRedirects; /// See [HttpClientRequest.persistentConnection]. /// /// Defaults to true. bool? persistentConnection; /// The default request encoder is [Utf8Encoder], you can set custom /// encoder by this option. RequestEncoder? requestEncoder; /// The default response decoder is [Utf8Decoder], you can set custom /// decoder by this option, it will be used in [Transformer]. ResponseDecoder? responseDecoder; /// Indicates the format of collection data in request query parameters and /// `x-www-url-encoded` body data. /// /// Defaults to [ListFormat.multi]. ListFormat? listFormat; ``` -------------------------------- ### Handle response as bytes Source: https://pub.dev/packages/dio/versions/5.4.3 Configures the request to return the response body as a list of bytes. ```dart final rs = await Dio().get>( url, options: Options(responseType: ResponseType.bytes), // Set the response type to `bytes`. ); print(rs.data); // Type: List. ``` -------------------------------- ### Set default HttpClientAdapter Source: https://pub.dev/packages/dio/versions/5.4.3 Assign a new instance of the default HttpClientAdapter to the Dio instance. ```dart dio.httpClientAdapter = HttpClientAdapter(); ``` -------------------------------- ### Listen to upload progress Source: https://pub.dev/packages/dio/versions/5.4.3 Uses the onSendProgress callback to track the progress of an upload. ```dart final response = await dio.post( 'https://www.dtworkroom.com/doris/1/2.0.0/test', data: {'aa': 'bb' * 22}, onSendProgress: (int sent, int total) { print('$sent $total'); }, ); ``` -------------------------------- ### Options Class Source: https://pub.dev/packages/dio/versions/5.4.3 The Options class defines the configuration for HTTP requests, including timeouts, headers, and response processing settings. ```APIDOC ## Options Class ### Description The `Options` class describes the HTTP request information and configuration. It can be used to set base configurations for a Dio instance or to override settings for a single request. ### Properties - **method** (String) - The HTTP request method. - **sendTimeout** (Duration?) - Timeout when sending data. - **receiveTimeout** (Duration?) - Timeout when receiving data. - **extra** (Map?) - Custom fields for use in Interceptors or Transformers. - **headers** (Map?) - HTTP request headers. - **preserveHeaderCase** (bool?) - Whether to preserve the case of header keys. - **responseType** (ResponseType?) - The expected format of the response (json, plain, bytes, stream). - **contentType** (String?) - The request content-type. - **validateStatus** (ValidateStatus?) - Callback to define if a status code is considered successful. - **receiveDataWhenStatusError** (bool?) - Whether to retrieve data if the status code indicates a failure. - **followRedirects** (bool?) - Whether to follow HTTP redirects. - **maxRedirects** (int?) - Maximum number of redirects allowed. - **persistentConnection** (bool?) - Whether to use persistent connections. - **requestEncoder** (RequestEncoder?) - Custom request encoder. - **responseDecoder** (ResponseDecoder?) - Custom response decoder. - **listFormat** (ListFormat?) - Format of collection data in query parameters and x-www-url-encoded bodies. ``` -------------------------------- ### Extract SHA256 fingerprint using OpenSSL Source: https://pub.dev/packages/dio/versions/5.4.3 Command line utility to retrieve the SHA256 fingerprint of a server certificate. ```bash openssl s_client -servername pinning-test.badssl.com -connect pinning-test.badssl.com:443 < /dev/null 2>/dev/null \ | openssl x509 -noout -fingerprint -sha256 # SHA256 Fingerprint=EE:5C:E1:DF:A7:A5:36:57:C5:45:C6:2B:65:80:2E:42:72:87:8D:AB:D6:5C:0A:AD:CF:85:78:3E:BB:0B:4D:5C # (remove the formatting, keep only lower case hex characters to match the `sha256` above) ``` -------------------------------- ### Post binary data with a Stream Source: https://pub.dev/packages/dio/versions/5.4.3 Sends binary data as a stream, requiring the content-length header to be set manually. ```dart // Binary data final postData = [0, 1, 2]; await dio.post( url, data: Stream.fromIterable(postData.map((e) => [e])), // Creates a Stream>. options: Options( headers: { Headers.contentLengthHeader: postData.length, // Set the content-length. }, ), ); ``` -------------------------------- ### Verify server certificate via fingerprint Source: https://pub.dev/packages/dio/versions/5.4.3 Uses IOHttpClientAdapter to validate the server certificate against a known SHA256 fingerprint. ```dart void initAdapter() { const String fingerprint = 'ee5ce1dfa7a53657c545c62b65802e4272878dabd65c0aadcf85783ebb0b4d5c'; dio.httpClientAdapter = IOHttpClientAdapter( createHttpClient: () { // Don't trust any certificate just because their root cert is trusted. final HttpClient client = HttpClient(context: SecurityContext(withTrustedRoots: false)); // You can test the intermediate / root cert here. We just ignore it. client.badCertificateCallback = (cert, host, port) => true; return client; }, validateCertificate: (cert, host, port) { // Check that the cert fingerprint matches the one we expect. // We definitely require _some_ certificate. if (cert == null) { return false; } // Validate it any way you want. Here we only check that // the fingerprint matches the OpenSSL SHA256. return fingerprint == sha256.convert(cert.der).toString(); }, ); } ``` -------------------------------- ### Verify certificate via SecurityContext Source: https://pub.dev/packages/dio/versions/5.4.3 Configures a SecurityContext with trusted certificates to validate the server chain. ```dart void initAdapter() { String PEM = 'XXXXX'; // root certificate content dio.httpClientAdapter = IOHttpClientAdapter( onHttpClientCreate: (_) { final SecurityContext sc = SecurityContext(); sc.setTrustedCertificates(File(pathToTheCertificate)); final HttpClient client = HttpClient(context: sc); return client; }, ); } ``` -------------------------------- ### Configure application/x-www-form-urlencoded format Source: https://pub.dev/packages/dio/versions/5.4.3 Set the content type to formUrlEncodedContentType at the instance level or per-request to override default JSON serialization. ```dart // Instance level dio.options.contentType = Headers.formUrlEncodedContentType; // or only works once dio.post( '/info', data: {'id': 5}, options: Options(contentType: Headers.formUrlEncodedContentType), ); ``` -------------------------------- ### Handle response as a stream Source: https://pub.dev/packages/dio/versions/5.4.3 Configures the request to return a response stream instead of the full body. ```dart final rs = await dio.get( url, options: Options(responseType: ResponseType.stream), // Set the response type to `stream`. ); print(rs.data.stream); // Response stream. ``` -------------------------------- ### Import dio in Dart Source: https://pub.dev/packages/dio/versions/5.4.3/install Include this import statement at the top of your Dart files to access the dio library. ```dart import 'package:dio/dio.dart'; ``` -------------------------------- ### Upload multiple files using FormData Source: https://pub.dev/packages/dio/versions/5.4.3 Adds multiple files to FormData using a list, which results in the upload key being suffixed with brackets. ```dart final formData = FormData.fromMap({ 'files': [ MultipartFile.fromFileSync('path/to/upload1.txt', filename: 'upload1.txt'), MultipartFile.fromFileSync('path/to/upload2.txt', filename: 'upload2.txt'), ], }); ``` -------------------------------- ### Add dependency to pubspec.yaml Source: https://pub.dev/packages/dio/versions/5.4.3/install Manually add this entry to the dependencies section of your pubspec.yaml file. ```yaml dependencies: dio: ^5.4.3 ``` -------------------------------- ### Verify certificate via badCertificateCallback Source: https://pub.dev/packages/dio/versions/5.4.3 Manual verification of a PEM certificate within the HttpClient callback. ```dart void initAdapter() { String PEM = 'XXXXX'; // root certificate content dio.httpClientAdapter = IOHttpClientAdapter( createHttpClient: () { final client = HttpClient(); client.badCertificateCallback = (X509Certificate cert, String host, int port) { return cert.pem == PEM; // Verify the certificate. }; return client; }, ); } ``` -------------------------------- ### Send FormData with Dio Source: https://pub.dev/packages/dio/versions/5.4.3 Constructs a FormData object with fields and a file, then sends it via a POST request. ```dart final formData = FormData.fromMap({ 'name': 'dio', 'date': DateTime.now().toIso8601String(), 'file': await MultipartFile.fromFile('./text.txt', filename: 'upload.txt'), }); final response = await dio.post('/info', data: formData); ``` -------------------------------- ### Perform POST request Source: https://pub.dev/packages/dio/versions/5.4.3 Sends a POST request with a map as the data payload. ```dart response = await dio.post('/test', data: {'id': 12, 'name': 'dio'}); ``` -------------------------------- ### Implement a Custom Interceptor Class Source: https://pub.dev/packages/dio/versions/5.4.3 Extend the Interceptor class to create reusable interceptor logic. ```dart import 'package:dio/dio.dart'; class CustomInterceptors extends Interceptor { @override void onRequest(RequestOptions options, RequestInterceptorHandler handler) { print('REQUEST[${options.method}] => PATH: ${options.path}'); super.onRequest(options, handler); } @override void onResponse(Response response, ResponseInterceptorHandler handler) { print('RESPONSE[${response.statusCode}] => PATH: ${response.requestOptions.path}'); super.onResponse(response, handler); } @override Future onError(DioException err, ErrorInterceptorHandler handler) async { print('ERROR[${err.response?.statusCode}] => PATH: ${err.requestOptions.path}'); super.onError(err, handler); } } ``` -------------------------------- ### Extend Dio Classes Source: https://pub.dev/packages/dio/versions/5.4.3 Extend DioForNative or DioForBrowser to customize Dio functionality, as the base Dio class is abstract. ```dart import 'package:dio/dio.dart'; import 'package:dio/io.dart'; // If in browser, import 'package:dio/browser.dart'. class Http extends DioForNative { Http([BaseOptions options]) : super(options) { // do something } } ``` -------------------------------- ### DioException class structure Source: https://pub.dev/packages/dio/versions/5.4.3 The structure of the DioException class, containing request metadata, response information, and error details. ```dart /// The request info for the request that throws exception. RequestOptions requestOptions; /// Response info, it may be `null` if the request can't reach to the /// HTTP server, for example, occurring a DNS error, network is not available. Response? response; /// The type of the current [DioException]. DioExceptionType type; /// The original error/exception object; /// It's usually not null when `type` is [DioExceptionType.unknown]. Object? error; /// The stacktrace of the original error/exception object; /// It's usually not null when `type` is [DioExceptionType.unknown]. StackTrace? stackTrace; /// The error message that throws a [DioException]. String? message; ``` -------------------------------- ### Dio request method signature Source: https://pub.dev/packages/dio/versions/5.4.3 The core API method signature for performing HTTP requests in Dio. ```dart Future> request( String path, { Object? data, Map? queryParameters, CancelToken? cancelToken, Options? options, ProgressCallback? onSendProgress, ProgressCallback? onReceiveProgress, }); ``` -------------------------------- ### Upload multiple files without list literal Source: https://pub.dev/packages/dio/versions/5.4.3 Manually adds multiple files to FormData to avoid the default array key suffixing behavior. ```dart final formData = FormData(); formData.files.addAll([ MapEntry( 'files', MultipartFile.fromFileSync('./example/upload.txt',filename: 'upload.txt'), ), MapEntry( 'files', MultipartFile.fromFileSync('./example/upload.txt',filename: 'upload.txt'), ), ]); ``` -------------------------------- ### Perform multiple concurrent requests Source: https://pub.dev/packages/dio/versions/5.4.3 Uses Future.wait to execute multiple requests simultaneously. ```dart response = await Future.wait([dio.post('/info'), dio.get('/token')]); ``` -------------------------------- ### Response Object Structure Source: https://pub.dev/packages/dio/versions/5.4.3 The Response object contains the data, status information, headers, and request metadata returned by a Dio request. ```APIDOC ## Response Object ### Description The Response object represents the result of an HTTP request made via Dio. ### Properties - **data** (T?) - The response body, potentially transformed. - **requestOptions** (RequestOptions) - The original request configuration. - **statusCode** (int?) - The HTTP status code. - **statusMessage** (String?) - The reason phrase associated with the status code. - **isRedirect** (bool) - Indicates if the response is a redirect. - **redirects** (List) - A list of redirects followed. - **extra** (Map) - Custom fields specific to the response. - **headers** (Headers) - The response headers. ``` -------------------------------- ### Define Response object structure Source: https://pub.dev/packages/dio/versions/5.4.3 The Response object contains metadata and data returned from a network request, including status codes, headers, and request options. ```dart /// Response body. may have been transformed, please refer to [ResponseType]. T? data; /// The corresponding request info. RequestOptions requestOptions; /// HTTP status code. int? statusCode; /// Returns the reason phrase associated with the status code. /// The reason phrase must be set before the body is written /// to. Setting the reason phrase after writing to the body. String? statusMessage; /// Whether this response is a redirect. /// ** Attention **: Whether this field is available depends on whether the /// implementation of the adapter supports it or not. bool isRedirect; /// The series of redirects this connection has been through. The list will be /// empty if no redirects were followed. [redirects] will be updated both /// in the case of an automatic and a manual redirect. /// /// ** Attention **: Whether this field is available depends on whether the /// implementation of the adapter supports it or not. List redirects; /// Custom fields that only for the [Response]. Map extra; /// Response headers. Headers headers; ``` -------------------------------- ### Access response data Source: https://pub.dev/packages/dio/versions/5.4.3 Retrieve data, headers, and status information from a successful Dio request. ```dart final response = await dio.get('https://pub.dev'); print(response.data); print(response.headers); print(response.requestOptions); print(response.statusCode); ``` -------------------------------- ### Send FormData Source: https://pub.dev/packages/dio/versions/5.4.3 Sends data using FormData, which is useful for multipart/form-data requests. ```dart final formData = FormData.fromMap({ 'name': 'dio', 'date': DateTime.now().toIso8601String(), }); final response = await dio.post('/info', data: formData); ``` -------------------------------- ### Customize JSON decoding in Flutter Source: https://pub.dev/packages/dio/versions/5.4.3 Use a top-level function with the compute method to decode JSON in a separate isolate for better performance. ```dart /// Must be top-level function Map _parseAndDecode(String response) { return jsonDecode(response) as Map; } Future> parseJson(String text) { return compute(_parseAndDecode, text); } void main() { // Custom `jsonDecodeCallback`. dio.transformer = DefaultTransformer()..jsonDecodeCallback = parseJson; runApp(MyApp()); } ``` -------------------------------- ### Add Interceptors using InterceptorsWrapper Source: https://pub.dev/packages/dio/versions/5.4.3 Use InterceptorsWrapper to define custom logic for request, response, and error handling within a Dio instance. ```dart dio.interceptors.add( InterceptorsWrapper( onRequest: (RequestOptions options, RequestInterceptorHandler handler) { // Do something before request is sent. // If you want to resolve the request with custom data, // you can resolve a `Response` using `handler.resolve(response)`. // If you want to reject the request with a error message, // you can reject with a `DioException` using `handler.reject(dioError)`. return handler.next(options); }, onResponse: (Response response, ResponseInterceptorHandler handler) { // Do something with response data. // If you want to reject the request with a error message, // you can reject a `DioException` object using `handler.reject(dioError)`. return handler.next(response); }, onError: (DioException error, ErrorInterceptorHandler handler) { // Do something with response error. // If you want to resolve the request with some custom data, // you can resolve a `Response` object using `handler.resolve(response)`. return handler.next(error); }, ), ); ``` -------------------------------- ### Reuse FormData safely Source: https://pub.dev/packages/dio/versions/5.4.3 Creates a new FormData instance for every request to prevent 'Cannot finalize' exceptions. ```dart Future _repeatedlyRequest() async { Future createFormData() async { return FormData.fromMap({ 'name': 'dio', 'date': DateTime.now().toIso8601String(), 'file': await MultipartFile.fromFile('./text.txt',filename: 'upload.txt'), }); } await dio.post('some-url', data: await createFormData()); } ``` -------------------------------- ### Cancel HTTP Requests Source: https://pub.dev/packages/dio/versions/5.4.3 Use a CancelToken to abort one or more ongoing requests simultaneously. ```dart final cancelToken = CancelToken(); dio.get(url, cancelToken: cancelToken).catchError((DioException error) { if (CancelToken.isCancel(error)) { print('Request canceled: ${error.message}'); } else { // handle error. } }); // Cancel the requests with "cancelled" message. token.cancel('cancelled'); ``` -------------------------------- ### Resolve or Reject Requests Manually Source: https://pub.dev/packages/dio/versions/5.4.3 Interfere with the execution flow by manually resolving or rejecting requests using the handler. ```dart dio.interceptors.add( InterceptorsWrapper( onRequest: (options, handler) { return handler.resolve( Response(requestOptions: options, data: 'fake data'), ); }, ), ); final response = await dio.get('/test'); print(response.data); // 'fake data' ``` -------------------------------- ### Specify FormData boundary name Source: https://pub.dev/packages/dio/versions/5.4.3 Configures a custom boundary name for the FormData object. ```dart final formDataWithBoundaryName = FormData( boundaryName: 'my-boundary-name', ); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.