|
|
|
|
// import 'dart:async';
|
|
|
|
|
// import 'dart:convert';
|
|
|
|
|
// import 'dart:io';
|
|
|
|
|
//
|
|
|
|
|
// import 'package:flutter/foundation.dart';
|
|
|
|
|
// import 'package:http/http.dart';
|
|
|
|
|
// import 'package:http/io_client.dart';
|
|
|
|
|
// import 'package:mohem_flutter_app/exceptions/api_exception.dart';
|
|
|
|
|
// import 'package:mohem_flutter_app/main.dart';
|
|
|
|
|
// import 'package:mohem_flutter_app/models/generic_mapper_model.dart';
|
|
|
|
|
// // ignore_for_file: avoid_annotating_with_dynamic
|
|
|
|
|
//
|
|
|
|
|
// typedef FactoryConstructor<U> = U Function(dynamic);
|
|
|
|
|
//
|
|
|
|
|
// class APIError {
|
|
|
|
|
// int? errorCode;
|
|
|
|
|
// int? errorType;
|
|
|
|
|
// String? errorMessage;
|
|
|
|
|
// int? errorStatusCode;
|
|
|
|
|
//
|
|
|
|
|
// APIError(this.errorCode, this.errorMessage, this.errorType, this.errorStatusCode);
|
|
|
|
|
//
|
|
|
|
|
// Map<String, dynamic> toJson() => {'errorCode': errorCode, 'errorMessage': errorMessage, 'errorType': errorType, 'ErrorStatusCode': errorStatusCode};
|
|
|
|
|
//
|
|
|
|
|
// @override
|
|
|
|
|
// String toString() {
|
|
|
|
|
// return jsonEncode(this);
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// APIException _throwAPIException(Response response) {
|
|
|
|
|
// switch (response.statusCode) {
|
|
|
|
|
// case 200:
|
|
|
|
|
// APIError? apiError;
|
|
|
|
|
// if (response.body != null && response.body.isNotEmpty) {
|
|
|
|
|
// var jsonError = jsonDecode(response.body);
|
|
|
|
|
// print(jsonError);
|
|
|
|
|
// apiError = APIError(jsonError['ErrorCode'], jsonError['ErrorMessage'], jsonError['ErrorType'], jsonError['ErrorStatusCode']);
|
|
|
|
|
// }
|
|
|
|
|
// return APIException(APIException.BAD_REQUEST, error: apiError);
|
|
|
|
|
// case 400:
|
|
|
|
|
// APIError? apiError;
|
|
|
|
|
// if (response.body != null && response.body.isNotEmpty) {
|
|
|
|
|
// var jsonError = jsonDecode(response.body);
|
|
|
|
|
// apiError = APIError(jsonError['ErrorCode'], jsonError['ErrorMessage'], jsonError['ErrorType'], jsonError['ErrorStatusCode']);
|
|
|
|
|
// }
|
|
|
|
|
// return APIException(APIException.BAD_REQUEST, error: apiError);
|
|
|
|
|
// case 401:
|
|
|
|
|
// return const APIException(APIException.UNAUTHORIZED);
|
|
|
|
|
// case 403:
|
|
|
|
|
// return const APIException(APIException.FORBIDDEN);
|
|
|
|
|
// case 404:
|
|
|
|
|
// return const APIException(APIException.NOT_FOUND);
|
|
|
|
|
// case 500:
|
|
|
|
|
// return const APIException(APIException.INTERNAL_SERVER_ERROR);
|
|
|
|
|
// case 444:
|
|
|
|
|
// var downloadUrl = response.headers["location"];
|
|
|
|
|
// return APIException(APIException.UPGRADE_REQUIRED, arguments: downloadUrl);
|
|
|
|
|
// default:
|
|
|
|
|
// return const APIException(APIException.OTHER);
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// class ApiClient {
|
|
|
|
|
// static final ApiClient _instance = ApiClient._internal();
|
|
|
|
|
//
|
|
|
|
|
// ApiClient._internal();
|
|
|
|
|
//
|
|
|
|
|
// factory ApiClient() => _instance;
|
|
|
|
|
//
|
|
|
|
|
// Future<U> postJsonForObject<T, U>(FactoryConstructor<U> factoryConstructor, String url, T jsonObject,
|
|
|
|
|
// {String? token, Map<String, dynamic>? queryParameters, Map<String, String>? headers, int retryTimes = 0, bool isFormData = false, bool returnJsonData = true}) async {
|
|
|
|
|
// var _headers = {'Accept': 'application/json'};
|
|
|
|
|
// if (headers != null && headers.isNotEmpty) {
|
|
|
|
|
// _headers.addAll(headers);
|
|
|
|
|
// }
|
|
|
|
|
// if (!kReleaseMode) {
|
|
|
|
|
// print("Url:$url");
|
|
|
|
|
// var bodyJson = json.encode(jsonObject);
|
|
|
|
|
// print("body:$bodyJson");
|
|
|
|
|
// }
|
|
|
|
|
// var response = await postJsonForResponse(url, jsonObject, token: token, queryParameters: queryParameters, headers: _headers, retryTimes: retryTimes, isFormData: isFormData);
|
|
|
|
|
// if (!kReleaseMode) {
|
|
|
|
|
// logger.i("res: " + response.body);
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// var jsonData = jsonDecode(response.body);
|
|
|
|
|
// GenericMapperModel res = GenericMapperModel.fromJson(jsonData);
|
|
|
|
|
// if (jsonData["IsAuthenticated"] != null) {
|
|
|
|
|
// AppState().setIsAuthenticated = jsonData["IsAuthenticated"];
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// if (res.messageStatus == 1 && res.errorMessage == null) {
|
|
|
|
|
//
|
|
|
|
|
// return res.data;
|
|
|
|
|
// return factoryConstructor(returnJsonData ? res.data : jsonData);
|
|
|
|
|
// } else {
|
|
|
|
|
// APIError? apiError;
|
|
|
|
|
// apiError = APIError(jsonData['ErrorCode'], res.errorEndUserMessage, jsonData['ErrorType'] ?? 0, jsonData['ErrorStatusCode']);
|
|
|
|
|
// throw APIException(APIException.BAD_REQUEST, error: apiError);
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// Future<Response> postJsonForResponse<T>(String url, T jsonObject,
|
|
|
|
|
// {String? token, Map<String, dynamic>? queryParameters, Map<String, String>? headers, int retryTimes = 0, bool isFormData = false}) async {
|
|
|
|
|
// String? requestBody;
|
|
|
|
|
// late Map<String, String> stringObj;
|
|
|
|
|
// if (jsonObject != null) {
|
|
|
|
|
// requestBody = jsonEncode(jsonObject);
|
|
|
|
|
// if (headers == null) {
|
|
|
|
|
// headers = {'Content-Type': 'application/json'};
|
|
|
|
|
// } else {
|
|
|
|
|
// headers['Content-Type'] = 'application/json';
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// if (isFormData) {
|
|
|
|
|
// headers = {'Content-Type': 'application/x-www-form-urlencoded'};
|
|
|
|
|
// stringObj = ((jsonObject ?? {}) as Map<String, dynamic>).map((key, value) => MapEntry(key, value?.toString() ?? ""));
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// return await _postForResponse(url, isFormData ? stringObj : requestBody, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes);
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// Future<Response> _postForResponse(String url, requestBody, {String? token, Map<String, dynamic>? queryParameters, Map<String, String>? headers, int retryTimes = 0}) async {
|
|
|
|
|
// try {
|
|
|
|
|
// var _headers = <String, String>{};
|
|
|
|
|
// if (token != null) {
|
|
|
|
|
// _headers['Authorization'] = 'Bearer $token';
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// if (headers != null && headers.isNotEmpty) {
|
|
|
|
|
// _headers.addAll(headers);
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// if (queryParameters != null) {
|
|
|
|
|
// var queryString = new Uri(queryParameters: queryParameters).query;
|
|
|
|
|
// url = url + '?' + queryString;
|
|
|
|
|
// }
|
|
|
|
|
// var response = await _post(Uri.parse(url), body: requestBody, headers: _headers).timeout(const Duration(seconds: 120));
|
|
|
|
|
//
|
|
|
|
|
// if (response.statusCode >= 200 && response.statusCode < 300) {
|
|
|
|
|
// return response;
|
|
|
|
|
// } else {
|
|
|
|
|
// throw _throwAPIException(response);
|
|
|
|
|
// }
|
|
|
|
|
// } on SocketException catch (e) {
|
|
|
|
|
// if (retryTimes > 0) {
|
|
|
|
|
// print('will retry after 3 seconds...');
|
|
|
|
|
// await Future.delayed(const Duration(seconds: 3));
|
|
|
|
|
// return await _postForResponse(url, requestBody, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes - 1);
|
|
|
|
|
// } else {
|
|
|
|
|
// throw APIException(APIException.OTHER, arguments: e);
|
|
|
|
|
// }
|
|
|
|
|
// } on HttpException catch (e) {
|
|
|
|
|
// if (retryTimes > 0) {
|
|
|
|
|
// print('will retry after 3 seconds...');
|
|
|
|
|
// await Future.delayed(const Duration(seconds: 3));
|
|
|
|
|
// return await _postForResponse(url, requestBody, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes - 1);
|
|
|
|
|
// } else {
|
|
|
|
|
// throw APIException(APIException.OTHER, arguments: e);
|
|
|
|
|
// }
|
|
|
|
|
// } on TimeoutException catch (e) {
|
|
|
|
|
// throw APIException(APIException.TIMEOUT, arguments: e);
|
|
|
|
|
// } on ClientException catch (e) {
|
|
|
|
|
// if (retryTimes > 0) {
|
|
|
|
|
// print('will retry after 3 seconds...');
|
|
|
|
|
// await Future.delayed(const Duration(seconds: 3));
|
|
|
|
|
// return await _postForResponse(url, requestBody, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes - 1);
|
|
|
|
|
// } else {
|
|
|
|
|
// throw APIException(APIException.OTHER, arguments: e);
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// Future<Response> getJsonForResponse<T>(String url, {String? token, Map<String, dynamic>? queryParameters, Map<String, String>? headers, int retryTimes = 0}) async {
|
|
|
|
|
// if (headers == null) {
|
|
|
|
|
// headers = {'Content-Type': 'application/json'};
|
|
|
|
|
// } else {
|
|
|
|
|
// headers['Content-Type'] = 'application/json';
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// if (!kReleaseMode) {
|
|
|
|
|
// print("Url:$url");
|
|
|
|
|
// // var bodyJson = json.encode(jsonObject);
|
|
|
|
|
// // print("body:$bodyJson");
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// return await _getForResponse(url, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes);
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// Future<Response> _getForResponse(String url, {String? token, Map<String, dynamic>? queryParameters, Map<String, String>? headers, int retryTimes = 0}) async {
|
|
|
|
|
// try {
|
|
|
|
|
// var _headers = <String, String>{};
|
|
|
|
|
// if (token != null) {
|
|
|
|
|
// _headers['Authorization'] = 'Bearer $token';
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// if (headers != null && headers.isNotEmpty) {
|
|
|
|
|
// _headers.addAll(headers);
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// if (queryParameters != null) {
|
|
|
|
|
// var queryString = new Uri(queryParameters: queryParameters).query;
|
|
|
|
|
// url = url + '?' + queryString;
|
|
|
|
|
// }
|
|
|
|
|
// var response = await _get(Uri.parse(url), headers: _headers).timeout(const Duration(seconds: 60));
|
|
|
|
|
//
|
|
|
|
|
// if (response.statusCode >= 200 && response.statusCode < 300) {
|
|
|
|
|
// return response;
|
|
|
|
|
// } else {
|
|
|
|
|
// throw _throwAPIException(response);
|
|
|
|
|
// }
|
|
|
|
|
// } on SocketException catch (e) {
|
|
|
|
|
// if (retryTimes > 0) {
|
|
|
|
|
// print('will retry after 3 seconds...');
|
|
|
|
|
// await Future.delayed(const Duration(seconds: 3));
|
|
|
|
|
// return await _getForResponse(url, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes - 1);
|
|
|
|
|
// } else {
|
|
|
|
|
// throw APIException(APIException.OTHER, arguments: e);
|
|
|
|
|
// }
|
|
|
|
|
// } on HttpException catch (e) {
|
|
|
|
|
// if (retryTimes > 0) {
|
|
|
|
|
// print('will retry after 3 seconds...');
|
|
|
|
|
// await Future.delayed(const Duration(seconds: 3));
|
|
|
|
|
// return await _getForResponse(url, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes - 1);
|
|
|
|
|
// } else {
|
|
|
|
|
// throw APIException(APIException.OTHER, arguments: e);
|
|
|
|
|
// }
|
|
|
|
|
// } on TimeoutException catch (e) {
|
|
|
|
|
// throw APIException(APIException.TIMEOUT, arguments: e);
|
|
|
|
|
// } on ClientException catch (e) {
|
|
|
|
|
// if (retryTimes > 0) {
|
|
|
|
|
// print('will retry after 3 seconds...');
|
|
|
|
|
// await Future.delayed(const Duration(seconds: 3));
|
|
|
|
|
// return await _getForResponse(url, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes - 1);
|
|
|
|
|
// } else {
|
|
|
|
|
// throw APIException(APIException.OTHER, arguments: e);
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// Future<Response> _get(url, {Map<String, String>? headers}) => _withClient((client) => client.get(url, headers: headers));
|
|
|
|
|
//
|
|
|
|
|
// bool _certificateCheck(X509Certificate cert, String host, int port) => true;
|
|
|
|
|
//
|
|
|
|
|
// Future<T> _withClient<T>(Future<T> Function(Client) fn) async {
|
|
|
|
|
// var httpClient = HttpClient()..badCertificateCallback = _certificateCheck;
|
|
|
|
|
// var client = IOClient(httpClient);
|
|
|
|
|
// try {
|
|
|
|
|
// return await fn(client);
|
|
|
|
|
// } finally {
|
|
|
|
|
// client.close();
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// Future<Response> _post(url, {Map<String, String>? headers, body, Encoding? encoding}) => _withClient((client) => client.post(url, headers: headers, body: body, encoding: encoding));
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
import 'dart:async';
|
|
|
|
|
import 'dart:convert';
|
|
|
|
|
import 'dart:io';
|
|
|
|
|
|
|
|
|
|
import 'package:flutter/foundation.dart';
|
|
|
|
|
import 'package:http/http.dart';
|
|
|
|
|
import 'package:http/io_client.dart';
|
|
|
|
|
import 'package:mohem_flutter_app/exceptions/api_exception.dart';
|
|
|
|
|
import 'package:mohem_flutter_app/main.dart';
|
|
|
|
|
// ignore_for_file: avoid_annotating_with_dynamic
|
|
|
|
|
|
|
|
|
|
typedef FactoryConstructor<U> = U Function(dynamic);
|
|
|
|
|
|
|
|
|
|
class APIError {
|
|
|
|
|
int? errorCode;
|
|
|
|
|
int? errorType;
|
|
|
|
|
String? errorMessage;
|
|
|
|
|
int? errorStatusCode;
|
|
|
|
|
|
|
|
|
|
APIError(this.errorCode, this.errorMessage, this.errorType, this.errorStatusCode);
|
|
|
|
|
|
|
|
|
|
Map<String, dynamic> toJson() => {'errorCode': errorCode, 'errorMessage': errorMessage, 'errorType': errorType, 'ErrorStatusCode': errorStatusCode};
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
String toString() {
|
|
|
|
|
return jsonEncode(this);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class ApiResponse<T> {
|
|
|
|
|
final int? totalItemsCount;
|
|
|
|
|
final T data;
|
|
|
|
|
final int? messageStatus;
|
|
|
|
|
final String? errorMessage;
|
|
|
|
|
final String? errorEndUserMessage;
|
|
|
|
|
|
|
|
|
|
ApiResponse({
|
|
|
|
|
required this.totalItemsCount,
|
|
|
|
|
required this.data,
|
|
|
|
|
required this.messageStatus,
|
|
|
|
|
this.errorMessage,
|
|
|
|
|
this.errorEndUserMessage,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
factory ApiResponse.fromJson(Map<String, dynamic> json, T Function(dynamic) fromJsonT) {
|
|
|
|
|
return ApiResponse<T>(
|
|
|
|
|
totalItemsCount: json['totalItemsCount'],
|
|
|
|
|
data: fromJsonT(json['data']),
|
|
|
|
|
messageStatus: json['messageStatus'],
|
|
|
|
|
errorMessage: json['errorMessage'],
|
|
|
|
|
errorEndUserMessage: json['errorEndUserMessage'],
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool get isSuccess => messageStatus == 1 && errorMessage == null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
APIException _throwAPIException(Response response) {
|
|
|
|
|
switch (response.statusCode) {
|
|
|
|
|
case 200:
|
|
|
|
|
APIError? apiError;
|
|
|
|
|
if (response.body != null && response.body.isNotEmpty) {
|
|
|
|
|
var jsonError = jsonDecode(response.body);
|
|
|
|
|
print(jsonError);
|
|
|
|
|
apiError = APIError(
|
|
|
|
|
jsonError['ErrorCode'] ?? jsonError['errorCode'],
|
|
|
|
|
jsonError['ErrorMessage'] ?? jsonError['errorMessage'],
|
|
|
|
|
jsonError['ErrorType'] ?? jsonError['errorType'],
|
|
|
|
|
jsonError['ErrorStatusCode'] ?? jsonError['errorStatusCode'],
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
return APIException(APIException.BAD_REQUEST, error: apiError);
|
|
|
|
|
case 400:
|
|
|
|
|
APIError? apiError;
|
|
|
|
|
if (response.body != null && response.body.isNotEmpty) {
|
|
|
|
|
var jsonError = jsonDecode(response.body);
|
|
|
|
|
apiError = APIError(
|
|
|
|
|
jsonError['ErrorCode'] ?? jsonError['errorCode'],
|
|
|
|
|
jsonError['ErrorMessage'] ?? jsonError['errorMessage'],
|
|
|
|
|
jsonError['ErrorType'] ?? jsonError['errorType'],
|
|
|
|
|
jsonError['ErrorStatusCode'] ?? jsonError['errorStatusCode'],
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
return APIException(APIException.BAD_REQUEST, error: apiError);
|
|
|
|
|
case 401:
|
|
|
|
|
return const APIException(APIException.UNAUTHORIZED);
|
|
|
|
|
case 403:
|
|
|
|
|
return const APIException(APIException.FORBIDDEN);
|
|
|
|
|
case 404:
|
|
|
|
|
return const APIException(APIException.NOT_FOUND);
|
|
|
|
|
case 500:
|
|
|
|
|
return const APIException(APIException.INTERNAL_SERVER_ERROR);
|
|
|
|
|
case 444:
|
|
|
|
|
var downloadUrl = response.headers["location"];
|
|
|
|
|
return APIException(APIException.UPGRADE_REQUIRED, arguments: downloadUrl);
|
|
|
|
|
default:
|
|
|
|
|
return const APIException(APIException.OTHER);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class ApiClient {
|
|
|
|
|
static final ApiClient _instance = ApiClient._internal();
|
|
|
|
|
|
|
|
|
|
ApiClient._internal();
|
|
|
|
|
|
|
|
|
|
factory ApiClient() => _instance;
|
|
|
|
|
|
|
|
|
|
Future<U> postJsonForObject<T, U>(
|
|
|
|
|
FactoryConstructor<U> factoryConstructor,
|
|
|
|
|
String url,
|
|
|
|
|
T jsonObject, {
|
|
|
|
|
String? token,
|
|
|
|
|
Map<String, dynamic>? queryParameters,
|
|
|
|
|
Map<String, String>? headers,
|
|
|
|
|
int retryTimes = 0,
|
|
|
|
|
bool isFormData = false,
|
|
|
|
|
bool returnJsonData = true,
|
|
|
|
|
}) async {
|
|
|
|
|
var _headers = {'Accept': 'application/json'};
|
|
|
|
|
if (headers != null && headers.isNotEmpty) {
|
|
|
|
|
_headers.addAll(headers);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!kReleaseMode) {
|
|
|
|
|
print("Url:$url");
|
|
|
|
|
var bodyJson = json.encode(jsonObject);
|
|
|
|
|
print("body:$bodyJson");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var response = await postJsonForResponse(
|
|
|
|
|
url,
|
|
|
|
|
jsonObject,
|
|
|
|
|
token: token,
|
|
|
|
|
queryParameters: queryParameters,
|
|
|
|
|
headers: _headers,
|
|
|
|
|
retryTimes: retryTimes,
|
|
|
|
|
isFormData: isFormData,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (!kReleaseMode) {
|
|
|
|
|
logger.i("res: " + response.body);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var jsonData = jsonDecode(response.body);
|
|
|
|
|
|
|
|
|
|
// Handle authentication flag if present
|
|
|
|
|
if (jsonData["IsAuthenticated"] != null) {
|
|
|
|
|
print("IsAuthenticated Need to be upated: ${jsonData["IsAuthenticated"]}");
|
|
|
|
|
// AppState().setIsAuthenticated = jsonData["IsAuthenticated"];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Create ApiResponse from the json
|
|
|
|
|
var apiResponse = ApiResponse.fromJson(jsonData, (res) => returnJsonData ? res : jsonData);
|
|
|
|
|
|
|
|
|
|
if (apiResponse.isSuccess) {
|
|
|
|
|
return factoryConstructor(apiResponse);
|
|
|
|
|
} else {
|
|
|
|
|
throw APIException(
|
|
|
|
|
APIException.BAD_REQUEST,
|
|
|
|
|
error: APIError(
|
|
|
|
|
null,
|
|
|
|
|
apiResponse.errorEndUserMessage ?? apiResponse.errorMessage,
|
|
|
|
|
null,
|
|
|
|
|
response.statusCode,
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Future<Response> postJsonForResponse<T>(
|
|
|
|
|
String url,
|
|
|
|
|
T jsonObject, {
|
|
|
|
|
String? token,
|
|
|
|
|
Map<String, dynamic>? queryParameters,
|
|
|
|
|
Map<String, String>? headers,
|
|
|
|
|
int retryTimes = 0,
|
|
|
|
|
bool isFormData = false,
|
|
|
|
|
}) async {
|
|
|
|
|
String? requestBody;
|
|
|
|
|
late Map<String, String> stringObj;
|
|
|
|
|
|
|
|
|
|
if (jsonObject != null) {
|
|
|
|
|
requestBody = jsonEncode(jsonObject);
|
|
|
|
|
if (headers == null) {
|
|
|
|
|
headers = {'Content-Type': 'application/json'};
|
|
|
|
|
} else {
|
|
|
|
|
headers['Content-Type'] = 'application/json';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (isFormData) {
|
|
|
|
|
headers = {'Content-Type': 'application/x-www-form-urlencoded'};
|
|
|
|
|
stringObj = ((jsonObject ?? {}) as Map<String, dynamic>).map(
|
|
|
|
|
(key, value) => MapEntry(key, value?.toString() ?? ""),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return await _postForResponse(
|
|
|
|
|
url,
|
|
|
|
|
isFormData ? stringObj : requestBody,
|
|
|
|
|
token: token,
|
|
|
|
|
queryParameters: queryParameters,
|
|
|
|
|
headers: headers,
|
|
|
|
|
retryTimes: retryTimes,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Future<Response> _postForResponse(
|
|
|
|
|
String url,
|
|
|
|
|
requestBody, {
|
|
|
|
|
String? token,
|
|
|
|
|
Map<String, dynamic>? queryParameters,
|
|
|
|
|
Map<String, String>? headers,
|
|
|
|
|
int retryTimes = 0,
|
|
|
|
|
}) async {
|
|
|
|
|
try {
|
|
|
|
|
var _headers = <String, String>{};
|
|
|
|
|
if (token != null) {
|
|
|
|
|
_headers['Authorization'] = 'Bearer $token';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (headers != null && headers.isNotEmpty) {
|
|
|
|
|
_headers.addAll(headers);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (queryParameters != null) {
|
|
|
|
|
var queryString = Uri(queryParameters: queryParameters).query;
|
|
|
|
|
url = url + '?' + queryString;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var response = await _post(
|
|
|
|
|
Uri.parse(url),
|
|
|
|
|
body: requestBody,
|
|
|
|
|
headers: _headers,
|
|
|
|
|
).timeout(const Duration(seconds: 120));
|
|
|
|
|
|
|
|
|
|
if (response.statusCode >= 200 && response.statusCode < 300) {
|
|
|
|
|
return response;
|
|
|
|
|
} else {
|
|
|
|
|
throw _throwAPIException(response);
|
|
|
|
|
}
|
|
|
|
|
} on SocketException catch (e) {
|
|
|
|
|
if (retryTimes > 0) {
|
|
|
|
|
print('will retry after 3 seconds...');
|
|
|
|
|
await Future.delayed(const Duration(seconds: 3));
|
|
|
|
|
return await _postForResponse(
|
|
|
|
|
url,
|
|
|
|
|
requestBody,
|
|
|
|
|
token: token,
|
|
|
|
|
queryParameters: queryParameters,
|
|
|
|
|
headers: headers,
|
|
|
|
|
retryTimes: retryTimes - 1,
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
throw APIException(APIException.OTHER, arguments: e);
|
|
|
|
|
}
|
|
|
|
|
} on HttpException catch (e) {
|
|
|
|
|
if (retryTimes > 0) {
|
|
|
|
|
print('will retry after 3 seconds...');
|
|
|
|
|
await Future.delayed(const Duration(seconds: 3));
|
|
|
|
|
return await _postForResponse(
|
|
|
|
|
url,
|
|
|
|
|
requestBody,
|
|
|
|
|
token: token,
|
|
|
|
|
queryParameters: queryParameters,
|
|
|
|
|
headers: headers,
|
|
|
|
|
retryTimes: retryTimes - 1,
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
throw APIException(APIException.OTHER, arguments: e);
|
|
|
|
|
}
|
|
|
|
|
} on TimeoutException catch (e) {
|
|
|
|
|
throw APIException(APIException.TIMEOUT, arguments: e);
|
|
|
|
|
} on ClientException catch (e) {
|
|
|
|
|
if (retryTimes > 0) {
|
|
|
|
|
print('will retry after 3 seconds...');
|
|
|
|
|
await Future.delayed(const Duration(seconds: 3));
|
|
|
|
|
return await _postForResponse(
|
|
|
|
|
url,
|
|
|
|
|
requestBody,
|
|
|
|
|
token: token,
|
|
|
|
|
queryParameters: queryParameters,
|
|
|
|
|
headers: headers,
|
|
|
|
|
retryTimes: retryTimes - 1,
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
throw APIException(APIException.OTHER, arguments: e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Future<Response> getJsonForResponse<T>(
|
|
|
|
|
String url, {
|
|
|
|
|
String? token,
|
|
|
|
|
Map<String, dynamic>? queryParameters,
|
|
|
|
|
Map<String, String>? headers,
|
|
|
|
|
int retryTimes = 0,
|
|
|
|
|
}) async {
|
|
|
|
|
if (headers == null) {
|
|
|
|
|
headers = {'Content-Type': 'application/json'};
|
|
|
|
|
} else {
|
|
|
|
|
headers['Content-Type'] = 'application/json';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!kReleaseMode) {
|
|
|
|
|
print("Url:$url");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return await _getForResponse(
|
|
|
|
|
url,
|
|
|
|
|
token: token,
|
|
|
|
|
queryParameters: queryParameters,
|
|
|
|
|
headers: headers,
|
|
|
|
|
retryTimes: retryTimes,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Future<ApiResponse<U>> getJsonForObject<T, U>(
|
|
|
|
|
FactoryConstructor<U> factoryConstructor,
|
|
|
|
|
String url, {
|
|
|
|
|
String? token,
|
|
|
|
|
Map<String, dynamic>? queryParameters,
|
|
|
|
|
Map<String, String>? headers,
|
|
|
|
|
int retryTimes = 0,
|
|
|
|
|
bool returnJsonData = true,
|
|
|
|
|
}) async {
|
|
|
|
|
var response = await getJsonForResponse(
|
|
|
|
|
url,
|
|
|
|
|
token: token,
|
|
|
|
|
queryParameters: queryParameters,
|
|
|
|
|
headers: headers,
|
|
|
|
|
retryTimes: retryTimes,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
var jsonData = jsonDecode(response.body);
|
|
|
|
|
|
|
|
|
|
// Handle authentication flag if present
|
|
|
|
|
if (jsonData["IsAuthenticated"] != null) {
|
|
|
|
|
print("IsAuthenticated Need to be upated: ${jsonData["IsAuthenticated"]}");
|
|
|
|
|
|
|
|
|
|
// AppState().setIsAuthenticated = jsonData["IsAuthenticated"];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var apiResponse = ApiResponse.fromJson(
|
|
|
|
|
jsonData,
|
|
|
|
|
(data) => returnJsonData ? data : jsonData,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (apiResponse.isSuccess) {
|
|
|
|
|
return ApiResponse<U>(
|
|
|
|
|
totalItemsCount: apiResponse.totalItemsCount,
|
|
|
|
|
data: factoryConstructor(apiResponse.data),
|
|
|
|
|
messageStatus: apiResponse.messageStatus,
|
|
|
|
|
errorMessage: apiResponse.errorMessage,
|
|
|
|
|
errorEndUserMessage: apiResponse.errorEndUserMessage,
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
throw APIException(
|
|
|
|
|
APIException.BAD_REQUEST,
|
|
|
|
|
error: APIError(
|
|
|
|
|
null,
|
|
|
|
|
apiResponse.errorEndUserMessage ?? apiResponse.errorMessage,
|
|
|
|
|
null,
|
|
|
|
|
response.statusCode,
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Future<Response> _getForResponse(
|
|
|
|
|
String url, {
|
|
|
|
|
String? token,
|
|
|
|
|
Map<String, dynamic>? queryParameters,
|
|
|
|
|
Map<String, String>? headers,
|
|
|
|
|
int retryTimes = 0,
|
|
|
|
|
}) async {
|
|
|
|
|
try {
|
|
|
|
|
var _headers = <String, String>{};
|
|
|
|
|
if (token != null) {
|
|
|
|
|
_headers['Authorization'] = 'Bearer $token';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (headers != null && headers.isNotEmpty) {
|
|
|
|
|
_headers.addAll(headers);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (queryParameters != null) {
|
|
|
|
|
var queryString = Uri(queryParameters: queryParameters).query;
|
|
|
|
|
url = url + '?' + queryString;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var response = await _get(
|
|
|
|
|
Uri.parse(url),
|
|
|
|
|
headers: _headers,
|
|
|
|
|
).timeout(const Duration(seconds: 60));
|
|
|
|
|
|
|
|
|
|
if (response.statusCode >= 200 && response.statusCode < 300) {
|
|
|
|
|
return response;
|
|
|
|
|
} else {
|
|
|
|
|
throw _throwAPIException(response);
|
|
|
|
|
}
|
|
|
|
|
} on SocketException catch (e) {
|
|
|
|
|
if (retryTimes > 0) {
|
|
|
|
|
print('will retry after 3 seconds...');
|
|
|
|
|
await Future.delayed(const Duration(seconds: 3));
|
|
|
|
|
return await _getForResponse(
|
|
|
|
|
url,
|
|
|
|
|
token: token,
|
|
|
|
|
queryParameters: queryParameters,
|
|
|
|
|
headers: headers,
|
|
|
|
|
retryTimes: retryTimes - 1,
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
throw APIException(APIException.OTHER, arguments: e);
|
|
|
|
|
}
|
|
|
|
|
} on HttpException catch (e) {
|
|
|
|
|
if (retryTimes > 0) {
|
|
|
|
|
print('will retry after 3 seconds...');
|
|
|
|
|
await Future.delayed(const Duration(seconds: 3));
|
|
|
|
|
return await _getForResponse(
|
|
|
|
|
url,
|
|
|
|
|
token: token,
|
|
|
|
|
queryParameters: queryParameters,
|
|
|
|
|
headers: headers,
|
|
|
|
|
retryTimes: retryTimes - 1,
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
throw APIException(APIException.OTHER, arguments: e);
|
|
|
|
|
}
|
|
|
|
|
} on TimeoutException catch (e) {
|
|
|
|
|
throw APIException(APIException.TIMEOUT, arguments: e);
|
|
|
|
|
} on ClientException catch (e) {
|
|
|
|
|
if (retryTimes > 0) {
|
|
|
|
|
print('will retry after 3 seconds...');
|
|
|
|
|
await Future.delayed(const Duration(seconds: 3));
|
|
|
|
|
return await _getForResponse(
|
|
|
|
|
url,
|
|
|
|
|
token: token,
|
|
|
|
|
queryParameters: queryParameters,
|
|
|
|
|
headers: headers,
|
|
|
|
|
retryTimes: retryTimes - 1,
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
throw APIException(APIException.OTHER, arguments: e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Future<Response> _get(url, {Map<String, String>? headers}) => _withClient((client) => client.get(url, headers: headers));
|
|
|
|
|
|
|
|
|
|
bool _certificateCheck(X509Certificate cert, String host, int port) => true;
|
|
|
|
|
|
|
|
|
|
Future<T> _withClient<T>(Future<T> Function(Client) fn) async {
|
|
|
|
|
var httpClient = HttpClient()..badCertificateCallback = _certificateCheck;
|
|
|
|
|
var client = IOClient(httpClient);
|
|
|
|
|
try {
|
|
|
|
|
return await fn(client);
|
|
|
|
|
} finally {
|
|
|
|
|
client.close();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Future<Response> _post(
|
|
|
|
|
url, {
|
|
|
|
|
Map<String, String>? headers,
|
|
|
|
|
body,
|
|
|
|
|
Encoding? encoding,
|
|
|
|
|
}) =>
|
|
|
|
|
_withClient((client) => client.post(
|
|
|
|
|
url,
|
|
|
|
|
headers: headers,
|
|
|
|
|
body: body,
|
|
|
|
|
encoding: encoding,
|
|
|
|
|
));
|
|
|
|
|
}
|