call<T> method
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);
}
}