call static method

Future<ResponseResult?> call({
  1. required ApiMethod method,
  2. required String name,
  3. String? baseUrl,
  4. ApiVersion version = ApiVersion.v1,
  5. String? contentType = Headers.jsonContentType,
  6. Map<String, dynamic>? queryParameters,
  7. Map<String, dynamic>? rawData = const {},
  8. FormData? formData,
  9. dynamic onResponse(
    1. Map<String, dynamic>
    )?,
  10. dynamic onError(
    1. DioException
    )?,
  11. BuildContext? dialogContext,
  12. bool showSnack = true,
})

Implementation

static Future<ResponseResult?> call({
  required ApiMethod method,
  required String name,
  String? baseUrl,
  ApiVersion version = ApiVersion.v1,
  String? contentType = Headers.jsonContentType,
  Map<String, dynamic>? queryParameters,
  Map<String, dynamic>? rawData = const {},
  FormData? formData,
  Function(Map<String, dynamic>)? onResponse,
  Function(DioException)? onError,
  BuildContext? dialogContext,
  bool showSnack = true,
}) async {
  //Check internet
  var result = await (Connectivity().checkConnectivity());
  //When no internet
  if (result.contains(ConnectivityResult.none)) {
    Cnt.messengerKey.currentState?.showSnackBar(
      SnackBar(
        margin: Pad.a12,
        behavior: SnackBarBehavior.floating,
        content: const SnackAlert(),
      ),
    );
  }

  bool canLoad = true;
  String sUrl = '${baseUrl ?? Str.baseUrl}$name';

  Response? response;

  Dio dio = Dio(
    BaseOptions(
      headers: {'Connection': 'keep-alive'},
      responseType: ResponseType.json,
    ),
  );

  dio.interceptors.add(
    InterceptorsWrapper(
      onRequest: (options, handler) async {
        canLoad = false;
        String sToken = Cnt.token;
        if (sToken.isNotEmpty) {
          options.headers['Authorization'] = 'Bearer $sToken';
        }
        if (kDebugMode) {
          dev.log(
            '\n───────── Start ─────────\nApi :: $sUrl\nMethod :: ${method.name}\nHeader :: ${options.headers}${options.queryParameters.isNotEmpty ? '\nParam :: ${options.queryParameters}' : ''}${options.data != null
                ? options.data is FormData
                      ? '\nTotal Files :: ${options.data.files.length}\nFields :: ${options.data.fields}'
                      : '\nData :: ${jsonEncode(options.data)}'
                : ''}\n───────── End ───────────\n',
            name: 'Input',
          );
        }
        return handler.next(options);
      },
      onResponse: (response, handler) {
        canLoad = true;
        if (kDebugMode) {
          dev.log(
            '\n─────────────────────────────────────────────────────── Start ───────────────────────────────────────────────────────\nApi :: $sUrl | StatusCode :: ${response.statusCode}\n${jsonEncode(response.data)}\n───────────────────────────────────────────────────────── End ───────────────────────────────────────────────────────\n',
            name: 'Output',
          );
        }
        onResponse != null ? onResponse(response.data) : null;
        return handler.next(response);
      },
      onError: (error, handler) async {
        canLoad = true;
        if (error.type != DioExceptionType.unknown) {
          if(showSnack){
            if (dialogContext != null) {
              Snack.showOnDialog(
                context: dialogContext,
                message:
                '${error.response?.data['message'] ?? error.response?.data['error']}',
              );
            } else {
              Snack.show(
                message:
                '${error.response?.data['message'] ?? error.response?.data['error']}',
              );
            }
          }
          if (kDebugMode) {
            dev.log(
              '\n───────── Start ─────────\nApi :: $sUrl\n${error.response?.data['message'] ?? error.response?.data['error']}\n───────── End ───────────\n',
              name: 'Error',
            );
          }
        } else {
          if (kDebugMode) {
            dev.log(
              '\n───────── Start ─────────\nApi :: $sUrl\n${error.error}\n───────── End ───────────\n',
              name: 'Error',
            );
          }
        }
        if (error.response?.statusCode == 401 || error.response?.statusCode == 403) {
          final data = error.response?.data;
          if (data is Map &&
              data['message']?.toString().toLowerCase().contains('expired token') ==
                  true) {
            if (Cnt.refreshToken.isEmpty) {
              await logout(data['message']);
              return handler.reject(error);
            }
            bool handled = false;
            final result = await LoginRepository().refreshToken();
            await result.when(
              success: (data) async {
                Pref.setValue(KV.token, data['token']);
                Pref.setValue(KV.refreshToken, data['refreshToken']);
                final options = error.requestOptions;
                final token = data['token']?.toString() ?? '';
                options.headers['Authorization'] =
                token.startsWith('Bearer ') ? token : 'Bearer $token';

                final cloneReq = await Dio().fetch(options);
                handled = true;
                handler.resolve(cloneReq);
              },
              failure: (msg) async {
                await logout(data['message']);
                handled = true;
                handler.reject(error);
              },
            );
            if (handled) return;
          }
        }
        onError != null ? onError(error) : null;
        return handler.next(error);
      },
    ),
  );
  try {
    if (canLoad) {
      switch (method) {
        case ApiMethod.get:
          response = await dio.get(
            sUrl,
            queryParameters: queryParameters,
            options: Options(contentType: contentType),
          );
          break;
        case ApiMethod.post:
          response = await dio.post(
            sUrl,
            queryParameters: queryParameters,
            data: contentType == Headers.jsonContentType
                ? jsonEncode(rawData)
                : formData,
            options: Options(contentType: contentType),
          );
          break;
        case ApiMethod.put:
          response = await dio.put(
            sUrl,
            queryParameters: queryParameters,
            data: contentType == Headers.jsonContentType
                ? jsonEncode(rawData)
                : formData,
            options: Options(contentType: contentType),
          );
          break;
        case ApiMethod.patch:
          response = await dio.patch(
            sUrl,
            queryParameters: queryParameters,
            data: contentType == Headers.jsonContentType
                ? jsonEncode(rawData)
                : formData,
            options: Options(contentType: contentType),
          );
          break;
        case ApiMethod.delete:
          response = await dio.delete(
            sUrl,
            queryParameters: queryParameters,
            data: contentType == Headers.jsonContentType
                ? jsonEncode(rawData)
                : formData,
            options: Options(contentType: contentType),
          );
          break;
      }
    }
    return responseFromJson({
      ...response?.data,
      'code': response?.statusCode,
    });
  } on DioException catch (e) {
    if (kDebugMode) {
      dev.log(
        '\n───────── Start ─────────\nApi :: $sUrl\n${e.message}\n───────── End ───────────\n',
        name: 'Error',
      );
    }
    onError != null ? onError(e) : null;
  } catch (e, stackTrace) {
    debugPrint('Error :: $e');
    debugPrint('Stack Trace: $stackTrace');
  }
  return null;
}