У меня есть текстовое поле для поиска городов. Когда я набираю символ, на сервер отправляется запрос (API). Когда я ввожу любой символ. Мне нужно отменить предыдущий запрос, который находится на рассмотрении. Помогите пожалуйста уважаемые профессионалы, Спасибо). Я не могу отменить свой предыдущий запрос
это httpService
Future<http.Response> httpGetPublic(path) async {
try {
var response = await http.get(Uri.parse(path), headers: {
HttpHeaders.contentTypeHeader: "application/json",
HttpHeaders.hostHeader: API.hostname,
HttpHeaders.cacheControlHeader: "no-cache",
HttpHeaders.acceptHeader: "application/json",
HttpHeaders.acceptEncodingHeader: "gzip, deflate, br",
}).timeout(
const Duration(seconds: 30),
onTimeout: () {
return http.Response('Connection Timeout', 408);
},
);
return response;
} catch (error) {
return http.Response('{"error":"${error.toString()}"}', 500);
}
}
этот метод получения данных
void fetchData(String query) async {
cities.clear();
_isLoading.value = true;
final response = await httpGetPublic("${API.cities}?name=$query");
try {
Iterable data = jsonDecode(utf8.decode(response.bodyBytes));
if (response.statusCode == 200) {
List<FlightCitiesModel> res = List<FlightCitiesModel>.from(
data.map((model) => FlightCitiesModel.fromJson(model)));
cities.addAll(res);
} else {
if (response.statusCode < 430) {
snackBarResponseError(responseData);
}
}
} catch (error) {
debugPrint("ERROR ====>");
debugPrint(error.toString());
}
_isLoading.value = false;
}
это мое текстовое поле поиска
TextField(
autofocus: true,
decoration: InputDecoration(
isDense: true,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
),
suffixIcon: const Icon(
Icons.search,
size: 26,
),
),
onChanged: (String value) {
if (value.length > 1) {
citiesController.setLoading();
}
if (_timer?.isActive ?? false) _timer!.cancel();
_timer = Timer(const Duration(milliseconds: 150), () {
citiesController.fetchData(value);
});
},
);
Вы можете добиться этого, используя функцию CancelToken
пакета http вместе с пакетом dio:
http
и dart:async
.import 'dart:async';
import 'package:http/http.dart' as http;
// Create a variable to hold the current request
http.CancelToken? _cancelToken;
// Modify your existing function to accept a cancel token
Future<http.Response> httpGetPublic(String path) async {
// Cancel the previous request if it exists
_cancelToken?.cancel();
// Create a new cancel token for this request
_cancelToken = http.CancelToken();
try {
var response = await http.get(
Uri.parse(path),
headers: {
HttpHeaders.contentTypeHeader: "application/json",
HttpHeaders.hostHeader: API.hostname,
HttpHeaders.cacheControlHeader: "no-cache",
HttpHeaders.acceptHeader: "application/json",
HttpHeaders.acceptEncodingHeader: "gzip, deflate, br",
},
// Pass the cancel token to the request
cancelToken: _cancelToken,
).timeout(
const Duration(seconds: 30),
onTimeout: () {
// Handle timeout
return http.Response('Connection Timeout', 408);
},
);
return response;
} catch (error) {
return http.Response('{"error":"${error.toString()}"}', 500);
}
}
Теперь, когда вы вызываете этот метод, он сначала отменяет существующий запрос, а затем вызывает новый.