call<T> method

Future<SmartApiResponse<T>> call<T>(
  1. SmartApiRequest request, {
  2. T fromJson(
    1. dynamic json
    )?,
})

Executes a fully-described request and returns a typed SmartApiResponse. This is what get, post, put and delete build a SmartApiRequest and delegate to — call it directly if you need full control (custom ApiMethod, forced multipart/raw, etc.).

Implementation

Future<SmartApiResponse<T>> call<T>(
  SmartApiRequest request, {
  T Function(dynamic json)? fromJson,
}) async {
  if (request.showLoader) SmartApiHooks.showLoader?.call();

  final online = await _hasNetwork();
  if (!online) {
    if (request.showLoader) SmartApiHooks.hideLoader?.call();
    return _awaitRetryOrFail<T>(request, fromJson);
  }

  final url = request.endpoint.startsWith('http')
      ? request.endpoint
      : '${SmartApiConfig.baseUrl}${request.endpoint}';

  final headers = <String, dynamic>{
    ...?SmartApiConfig.headerBuilder?.call(),
    ...?request.extraHeaders,
  };

  try {
    final payload = await _resolveBody(
      request.body,
      forceMultipart: request.forceMultipart,
      forceRaw: request.forceRaw,
      autoDetectFiles: request.autoDetectFiles ?? SmartApiConfig.autoDetectFiles,
      files: request.files,
    );
    final options = Options(headers: headers);

    final query = <String, dynamic>{
      if (request.method == ApiMethod.get && request.body is Map)
        ...(request.body as Map).cast<String, dynamic>(),
      ...?request.queryParams,
    };
    final queryParameters = query.isEmpty ? null : query;

    Response response;
    switch (request.method) {
      case ApiMethod.get:
        response = await _dio.get(url, queryParameters: queryParameters, options: options);
        break;
      case ApiMethod.post:
        response = await _dio.post(url, data: payload, queryParameters: queryParameters, options: options);
        break;
      case ApiMethod.put:
        response = await _dio.put(url, data: payload, queryParameters: queryParameters, options: options);
        break;
      case ApiMethod.patch:
        response = await _dio.patch(url, data: payload, queryParameters: queryParameters, options: options);
        break;
      case ApiMethod.delete:
        response = await _dio.delete(url, data: payload, queryParameters: queryParameters, options: options);
        break;
    }

    if (request.showLoader) SmartApiHooks.hideLoader?.call();

    final envelope = (SmartApiConfig.responseParser ?? SmartApiEnvelope.defaultParse)
        .call(response.data);

    return SmartApiResponse<T>(
      success: envelope.success,
      message: envelope.message,
      statusCode: response.statusCode,
      data: fromJson != null && envelope.data != null
          ? fromJson(envelope.data)
          : envelope.data as T?,
      raw: response.data,
    );
  } on DioException catch (e) {
    if (request.showLoader) SmartApiHooks.hideLoader?.call();
    return _handleDioError<T>(e);
  } catch (e) {
    if (request.showLoader) SmartApiHooks.hideLoader?.call();
    const msg = "Something went wrong. Try again.";
    SmartApiHooks.showMessage?.call(msg, type: SmartApiMsgType.error);
    return SmartApiResponse<T>(success: false, message: msg);
  }
}