Dio: When cancel called. Requests isn't canceled - flutter

I have problem with canceling requests using Dio api client.
final cancelToken = CancelToken();
final request = host.request(path,
data: data,
queryParameters: query,
options: Options(method: describeEnum(method)),
cancelToken: cancelToken);
final cancelableRequest = CancelableOperation.fromFuture(request, onCancel: () {
cancelToken.cancel();
});
When cancelToken.cancel(); is called I receive DioErrorType.CANCEL but request is not canceled (checked in Charles web proxy). I have tried throttling request but it always waits for response.

Try to write this way to cancel Dio api calling
CancelToken cancelToken = CancelToken();
Request request = host.request(path,
data: data,
queryParameters: query,
options: Options(method: describeEnum(method)),
cancelToken: cancelToken);
// cancel the requests with "cancelled" message.
final cancelableRequest = CancelableOperation.fromFuture(request, onCancel: token.cancel("cancelled"));

Related

How to catch an Error for timeout on http.client Flutter

I have a Future that calls a POST API using the http.client structure.
At the moment there is an issue with said API and my call is timing out before the full header is received, giving me a unhandled exception.
How is the best way to return this exception and show a snackbar of the issue returned?
Future<dynamic> get() async {
try {
var response = await client.post(
Uri.parse(Url),
headers: headers,
body: body,
);
}
here is the simple http call to catch an Error for timeout
return the error and catch this where from you handle the api call
import 'package:http/http.dart';
Future<dynamic> get() async {
try {
var response = await post(
Uri.parse(Url),
headers: headers,
body: body,
).timeout(Duration(seconds: 2), onTimeout: (){
/// here is the response if api call time out
/// you can show snackBar here or where you handle api call
return Response('Time out!', 500);
});
}catch(e){
print(e);
}
}
you can change your duration in the timeout method

How to fire interceptor with post request and set configurable dio interceptor work every api app

I want to know dio post request how perform interceptor 'onrequest' in response 'onerror'
Above code in 'onerror' request refresh token not working interceptor also any other way
Future getlist() async{
final dio = Dio();
Final storage=Fluttersecurestorage();
String accesstoken =await storage.read('accesstoken');
final response= await dio.post(
url,
data: loginData,
options: Options(headers: {"authorization": 'Bearer $accesstoken'}),
dio.interceptors.clear();
dio.interceptors.add(
InterceptorsWrapper(
onRequest: (request, handler) {
},
onError: (err, handler) async {
if (err.response?.statusCode == 401) {
//request refresh token}
}
}
));

Flutter - http.MultipartRequest() does not work normally

I am using http package(http: ^0.13.3) in flutter for sending request to the server.
In postman, I can send request and receive response, but in android emulator I can't receive response normally.
Curious thing is that yesterday I can receive response from server, but now I can't receive response.
when, I can receive response from server, when, I can't receive response from server.
But in postman I can receive response always well.
static Future<ResObj?> post(
String url, Map<String, String> data, String? token) async {
try {
var request = new http.MultipartRequest('POST', Uri.parse(url));
request.headers.addAll({
"Authorization": token ?? "",
"Content-Type": "multipart/form-data"
});
data.forEach((key, value) {
request.fields[key] = value;
});
var streamResponse = await request.send();
print(streamResponse);
final responseString = await streamResponse.stream.bytesToString();
if (streamResponse.statusCode == 200) {
final dynamic jsonMap = json.decode(responseString);
return ResObj(
status: true, code: streamResponse.statusCode, data: jsonMap);
} else {
return ResObj(
status: false, code: streamResponse.statusCode, error: "error");
}
} catch (e) {
print(e);
return ResObj(status: false, error: "unknown");
}
}
And postman setting is
In code, I can't receive print(streamResponse), yesterday's code is same as current.
I didn't change my code today.
In code, post function's parameters(url, data, token) are normal.
In my thought, await request.send() function is not working now, but I can't catch any error.
Server is also same status as yesterday, I swear.
Maybe, Is this because of http package?
Please help me to fix this error.

Dio Cancel current running API before starting a new API request

I am using DIO package for API request but the issue is that when I request for another API while the first API is still in progress.
It doesn't cancel the first request. Both the APIs run simultaneously which is not the desired in my app scenario.
class DioClient {
static BaseOptions options = BaseOptions(baseUrl: baseUrl);
Dio _dio = Dio(options);
Future<dynamic> postFormData(
{dynamic data, String url, dynamic header}) async {
final data1 = data;
var formData = FormData.fromMap(data1);
try {
var response = await _dio.post(url,
options: Options(headers: header), data: formData);
return response.data;
} catch (e) {
throw e;
}}}
If you want to cancel the API request call then you need to use the cancel token provided by DIO.
You need to pass cancel token in dio request when you make other API call use that cancel token to cancel the API request
Here is the code
class DioClient {
static BaseOptions options = BaseOptions(baseUrl: baseUrl);
//Here is line you need
CancelToken cancelToken=CancelToken();
Dio _dio = Dio(options);
Future<dynamic> postFormData(
{dynamic data, String url, dynamic header}) async {
final data1 = data;
var formData = FormData.fromMap(data1);
try {
//pass cancel token here
var response = await _dio.post(url,
options: Options(headers: header), data: formData,cancelToken: cancelToken);
return response.data;
} catch (e) {
throw e;
}}}
And use that cancelToken to cancel the API request when you call another API first you cancel the previous request.
cancelToken.cancel();
Enjoy!

Flutter Dio interceptor: DioError [DioErrorType.DEFAULT]: Bad state: Can‘t finalize a finalized MultipartFile

Hi i'm trying refreshtoken logic in Dio interceptor. it's working fine for json body params, but its throwing DioError [DioErrorType.DEFAULT]: Bad state: Can‘t finalize a finalized MultipartFile when i tried uploading images.
onError: (DioError error) async {
// Do something with response error
if (error.response?.statusCode == 401) {
// _dio.interceptors.requestLock.lock();
Response response;
RequestOptions options = error.response.request;
response = await _dio
.post('/user/refresh', data: {"refreshToken": _refreshToken});
if (response.statusCode == 200) {
final userData = json.encode(
{
'token': response.data["accessToken"],
'tokenType': _tokenType,
'refreshToken': response.data["refreshToken"]
},
);
prefs.setString('userData', userData);
options.data = formData;
}
options.headers["Authorization"] =
"$_tokenType ${response.data['accessToken']}";
return await _dio.request(options.path, options: options);
} else {
throw error;
}
I put together a workaround for this issue which basically consists of rebuilding the FormData before retrying. It feels a bit hacky but it works. I start by passing any info I need for the reconstruction in via the "extra" map in the request options so the interceptor has access to it. Here is some pseudo code:
//original request
dioResponse = await dio.post(
'http://my/api/endpoint',
data: myOriginalFormData,
options: Options(
headers: myHeaders,
extra: {'pathToMyFile': pathToMyFile},
),
);
//and in my interceptor I use it to construct a fresh FormData that has not been finalized
final FormData newFormData = FormData.fromMap({
'file': await MultipartFile.fromFile(
requestOptions.extra['pathToMyFile'],
contentType: MediaType('application/json', 'json')),
});
//retry with the fresh FormData
return dio.request(
requestOptions.path,
data: newFormData,
options: requestOptions,
cancelToken: requestOptions.cancelToken,
onReceiveProgress: requestOptions.onReceiveProgress,
onSendProgress: requestOptions.onSendProgress,
queryParameters: requestOptions.queryParameters,
);
Anyone have thoughts on this approach? Any major downsides?