request method

Future<ResponseModal> request({
  1. required ApiMethod method,
  2. required String url,
  3. dynamic requestData,
  4. Map<String, dynamic>? headers,
  5. void authTokenCallback()?,
  6. Map<String, dynamic>? queryParameters,
  7. bool useWithoutToken = false,
  8. bool cacheResponse = false,
  9. Duration cacheDuration = const Duration(minutes: 30),
  10. bool forceOffline = false,
  11. CancelToken? cancelToken,
  12. void onSendProgress(
    1. int,
    2. int
    )?,
  13. void onReceiveProgress(
    1. int,
    2. int
    )?,
  14. BuildContext? context,
  15. bool showSuccessMessage = false,
  16. bool showErrorMessage = true,
  17. bool showErrorLog = true,
  18. bool showSuccessLog = true,
})

Implementation

Future<ResponseModal> request({
  required ApiMethod method,
  required String url,
  dynamic requestData,
  Map<String, dynamic>? headers,
  void Function()? authTokenCallback,
  Map<String, dynamic>? queryParameters,
  bool useWithoutToken = false,
  bool cacheResponse = false,
  Duration cacheDuration = const Duration(minutes: 30),
  bool forceOffline = false,
  CancelToken? cancelToken,
  void Function(int, int)? onSendProgress,
  void Function(int, int)? onReceiveProgress,
  BuildContext? context,
  bool showSuccessMessage = false,
  bool showErrorMessage = true,
  bool showErrorLog = true,
  bool showSuccessLog = true,
}) async
{
  try {
    // Check if we should force offline mode
    if (forceOffline) {
      print('Force offline mode enabled');
      if (!_enableCache) {
        print('Cache not enabled, cannot use offline mode');
        throw {'error': 'Cache not enabled, cannot use offline mode'};
      }
      final cached = _cacheBox.get(url);
      if (cached != null) return cached['data']??cached;
      print('No cached data available');
      throw {'error': 'No cached data available'};
    }

    // Make the request
    late Response response;
    final options = Options(
      headers: headers,
      extra: {
        'useWithoutToken': useWithoutToken,
        'cacheResponse': cacheResponse,
        'cacheDuration': cacheDuration.inMilliseconds,
      },
    );

    switch (method) {
      case ApiMethod.get:
        response = await _dio.get(
          url,
          queryParameters: queryParameters,
          options: options,
          cancelToken: cancelToken,
          onReceiveProgress: onReceiveProgress,
        );
        break;
      case ApiMethod.post:
        response = await _dio.post(
          url,
          data: requestData,
          queryParameters: queryParameters,
          options: options,
          cancelToken: cancelToken,
          onSendProgress: onSendProgress,
        );
        break;
      case ApiMethod.put:
        response = await _dio.put(
          url,
          data: requestData,
          queryParameters: queryParameters,
          options: options,
          cancelToken: cancelToken,
          onSendProgress: onSendProgress,
        );
        break;
      case ApiMethod.patch:
        response = await _dio.patch(
          url,
          data: requestData,
          queryParameters: queryParameters,
          options: options,
          cancelToken: cancelToken,
          onSendProgress: onSendProgress,
        );
        break;
      case ApiMethod.delete:
        response = await _dio.delete(
          url,
          data: requestData,
          queryParameters: queryParameters,
          options: options,
          cancelToken: cancelToken,
        );
        break;
    }

    // Cache response if needed
    if (_enableCache && cacheResponse) {
      await _cacheBox.put(
        url,
        response.data,
      );
    }
    final responseModal = ResponseModal.fromDioResponse(response);
    if(showSuccessLog){
      log('Response is ${responseModal.data}');
    }

    if (responseModal.status == 1 && showSuccessMessage) {
      _showSnackbar(context, responseModal.message, isError: false);
    } else if (responseModal.status == 0 && showErrorMessage) {
      _showSnackbar(context, responseModal.message, isError: true);
    }

    return responseModal;
  } on DioException catch (e) {
    if(showErrorLog){
      log('Dio Response: ${e.response}');
    }
    // Handle Dio errors (including status 400)
    if (e.response != null) {
      try {
        final errorResponse = e.response?.data;
        if (e.response?.statusCode == 401) {
          authTokenCallback?.call();
          print('Authorization failed: $errorResponse');
        }

        if (errorResponse is Map && errorResponse['message'] != null) {
          if(showErrorMessage){
            _showSnackbar(context, errorResponse['message'], isError: true);
          }
          return ResponseModal(
            message: errorResponse['message'],
            data: errorResponse['data'] ?? {},
            status: errorResponse['status'] ?? 0,
            error: errorResponse['error'] ?? {},
            fullData: errorResponse,
          );
        }

      } catch (parseError) {
        print('Error parsing error response: $parseError');
      }
    }

    if (e.error == 'No internet connection') {
      _showSnackbar(context, 'No internet connection');
    } else {
      print('API Error: ${e.message}');
      if(kDebugMode){
        _showSnackbar(context, e.message ?? 'An error occurred');
      }
    }

    return ResponseModal(
      message: e.message ?? 'An error occurred',
      data: {},
      status: 0,
      error: {'error': e.toString()},
      fullData: e.response?.data ?? {},
    );
  } catch (e) {
    final errorModal = ResponseModal(
      message: e.toString(),
      data: {},
      status: 0,
      error: {'error': e.toString()},
      fullData: {},
    );

    _showSnackbar(context, e.toString());
    print('Error in catch: ${e.toString()}');
    return errorModal;
  }
}