apiClientTemplate function
Implementation
String apiClientTemplate() {
return '''
import 'dart:io';
import 'package:dio/dio.dart';
import '../constants/app_strings.dart';
import 'api_interceptor.dart';
import 'api_response.dart';
import 'api_exception.dart';
class ApiClient {
late final Dio _dio;
ApiClient(String baseUrl) {
_dio = Dio(
BaseOptions(
baseUrl: baseUrl,
connectTimeout: const Duration(seconds: 30),
receiveTimeout: const Duration(seconds: 30),
headers: {
"Content-Type": "application/json",
'UtcOffsetInSecond': "19800",
'AppVersion': '1',
'DeviceTypeId': Platform.isIOS ? '2' : '1',
'LanguageCode': 'en',
},
),
);
_dio.interceptors.add(ApiInterceptor());
// if (kDebugMode) { ... }
}
/// ✅ New Centralized Request Handler
Future<ApiResponse> _performRequest(Future<Response> Function() request) async {
try {
final response = await request();
return ApiResponse.success(response.data);
} catch (e) {
if (e is DioException) {
/// 1️⃣ First check interceptor exception
if (e.error is ApiException) {
return ApiResponse.error(e.error.toString());
}
/// 2️⃣ Then check server response
if (e.response != null) {
final data = e.response?.data;
if (data is Map<String, dynamic>) {
return ApiResponse.error(data["message"] ?? "Server error");
}
return ApiResponse.error("Server error");
}
/// 3️⃣ Network error
return ApiResponse.error(e.message ?? "Network error");
}
/// Non-Dio Exceptions (Network connectivity, parsing, etc.)
return ApiResponse.error(AppStrings.commonError);
}
}
/// 👇 The public methods are now clean and only 1 line each!
Future<ApiResponse> get(String path, {Map<String, dynamic>? query}) {
return _performRequest(() => _dio.get(path, queryParameters: query));
}
Future<ApiResponse> post(String path, {dynamic data}) {
return _performRequest(() => _dio.post(path, data: data));
}
Future<ApiResponse> put(String path, {dynamic data}) {
return _performRequest(() => _dio.put(path, data: data));
}
Future<ApiResponse> delete(String path) {
return _performRequest(() => _dio.delete(path));
}
Future<ApiResponse> multipart(
String path,
Map<String, dynamic> fields,
Map<String, MultipartFile> files,
) {
final formData = FormData.fromMap({...fields, ...files});
return _performRequest(
() => _dio.post(
path,
data: formData,
options: Options(contentType: "multipart/form-data"),
),
);
}
void setToken(String token){
_dio.options.headers["Authorization"] = "Bearer \$token";
}
}
''';
}