I have to Tab in Tabbar button, and when user click on each tab is send a request with different query params, now if user tap of get_cars and quickly before getting data click on tab of get_drivers the data of get_cars show and after that data of get_drivers show, but i WANT===>
when user click on another option, cancel the previous requests and send the current option request.
now I just want it on get requests
and that is my code and I use Dio package
import 'dart:convert';
import 'dart:developer';
import 'package:dio/dio.dart';
import 'package:untitled/core/error/exceptions.dart';
import 'package:untitled/core/platform/network_urls.dart';
import 'package:untitled/routes/app_router.dart';
import 'package:untitled/routes/app_router.gr.dart';
import '../get_it/get_it.dart';
import '../local_storage/keys.dart';
import '../local_storage/local_storage.dart';
abstract class HttpRequests {
Future<Response> get(String url);
Future<Response> post(String url, {Object? body});
Future<Response> delete(String url);
Future<Response> patch(String url, {Object? body});
void cancelRequests(); // Method to cancel requests
}
class HttpRequestsImp extends HttpRequests {
final LocalStorage localStorage = sl<LocalStorage>();
late CancelToken cancelToken;
late final Dio dio;
HttpRequestsImp() {
cancelToken = CancelToken();
dio = Dio(BaseOptions(
baseUrl: BASE_API_URL,
connectTimeout: Duration(seconds: 10),
receiveTimeout: Duration(seconds: 10),
contentType: Headers.jsonContentType,
responseType: ResponseType.json,
))
..interceptors.add(InterceptorsWrapper(
onRequest: (options, handler) {
final userCredentials = localStorage.read(USER_CREDENTIALS);
if (userCredentials != null) {
final userMapData = jsonDecode(userCredentials);
options.headers['Authorization'] =
'Bearer ${userMapData["token"]['accessToken']}';
}
return handler.next(options);
},
onResponse: (response, handler) {
return handler.next(
response); // continue with the response which will be returned
},
onError: (DioException e, handler) async {
if (e.type == DioExceptionType.cancel) {
log('DioError: ${e.message}');
return;
}
if (e.response?.statusCode == 401) {
try {
final newAccessToken = await getNewAccessToken();
if (newAccessToken.isNotEmpty) {
e.requestOptions.headers['Authorization'] =
'Bearer $newAccessToken';
final retryResponse = await dio.request(
e.requestOptions.path,
options: Options(
method: e.requestOptions.method,
headers: e.requestOptions.headers,
),
data: e.requestOptions.data,
queryParameters: e.requestOptions.queryParameters,
cancelToken: cancelToken, // Apply cancel token on retry
);
return handler.resolve(retryResponse);
}
} catch (tokenError) {
log('Token refresh failed: $tokenError');
final router = sl<AppRouter>();
router.push(const Login());
}
}
return handler.next(e);
},
));
}
Future<String> getNewAccessToken() async {
try {
final userCredentials = localStorage.read(USER_CREDENTIALS);
final userMapData = jsonDecode(userCredentials);
final response = await dio.post(
'/auth/token/refresh',
data: {'refreshToken': userMapData['token']['refreshToken']},
cancelToken: cancelToken, // Apply cancel token here as well
);
if (response.statusCode != 200) {
localStorage.delete(USER_CREDENTIALS);
final router = sl<AppRouter>();
router.push(const Login());
return "";
} else {
final data = response.data as Map<String, dynamic>;
userMapData['token']['accessToken'] = data['payload']['accessToken'];
userMapData['token']['refreshToken'] = data['payload']['refreshToken'];
await localStorage.write(USER_CREDENTIALS, jsonEncode(userMapData));
return data['payload']['accessToken'];
}
} catch (e) {
log('Failed to get new access token: $e');
localStorage.delete(USER_CREDENTIALS);
final router = sl<AppRouter>();
router.push(const Login());
return "";
}
}
@override
Future<Response> get(String url) async {
cancelToken.cancel('cancelled');
print(cancelToken.isCancelled);
cancelToken = CancelToken();
final response = await dio.get(url, cancelToken: cancelToken);
if (response.statusCode! >= 500) {
throw ServerException(response.data);
}
return response;
}
@override
Future<Response> post(String url, {Object? body}) async {
final response = await dio.post(url, data: body, cancelToken: cancelToken);
if (response.statusCode! >= 500) {
throw ServerException(response.data);
}
return response;
}
@override
Future<Response> delete(String url) async {
final response = await dio.delete(url, cancelToken: cancelToken);
if (response.statusCode! >= 500) {
throw ServerException(response.data);
}
return response;
}
@override
Future<Response> patch(String url, {Object? body}) async {
final response = await dio.patch(url, data: body, cancelToken: cancelToken);
if (response.statusCode! >= 500) {
throw ServerException(response.data);
}
return response;
}
@override
void cancelRequests() {}
}