Skip to content

Instantly share code, notes, and snippets.

@MisterJimson
Created June 24, 2020 23:10
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MisterJimson/da0a9acb4cdba7138ebab864fb93cb32 to your computer and use it in GitHub Desktop.
Save MisterJimson/da0a9acb4cdba7138ebab864fb93cb32 to your computer and use it in GitHub Desktop.
import 'dart:typed_data';
import 'package:http/http.dart' as http;
import 'package:meta/meta.dart';
import 'dart:convert';
bool _isSuccessStatusCode(int code) => (code >= 200 && code < 300);
class ApiResponse<T> {
final int statusCode;
T data;
String error;
bool get isSuccess => _isSuccessStatusCode(statusCode);
ApiResponse(this.statusCode, {this.data, this.error});
}
typedef FromJson<T> = T Function(Map<String, dynamic>);
Future<ApiResponse<T>> get<T>(
{@required String url,
@required FromJson<T> fromJson,
bool useFromJsonOnFailure = false,
Map<String, String> headers}) async {
try {
var response = await http.get(url, headers: headers);
return _handleResult(response, fromJson, useFromJsonOnFailure);
} catch (e, stack) {
Logger.logEvent(
'API fail: URL: $url, Error: ${e.toString()}',
exception: e,
stackTrace: stack,
);
return ApiResponse(-1, error: e.toString());
}
}
Future<ApiResponse<Uint8List>> getByteArray(
{@required String url, Map<String, String> headers}) async {
try {
var response = await http.get(url, headers: headers);
return _handleByteArrayResult(response);
} catch (e, stack) {
Logger.logEvent(
'API fail: URL: $url, Error: ${e.toString()}',
exception: e,
stackTrace: stack,
);
return ApiResponse(-1, error: e.toString());
}
}
Future<ApiResponse<List<T>>> getList<T>(
{@required String url,
@required FromJson<T> fromJson,
Map<String, String> headers}) async {
try {
var response = await http.get(url, headers: headers);
return _handleListResult(response, fromJson);
} catch (e, stack) {
Logger.logEvent(
'API fail: URL: $url, Error: ${e.toString()}',
exception: e,
stackTrace: stack,
);
return ApiResponse(-1, error: e.toString());
}
}
Future<ApiResponse<T>> post<T>(
{@required String url,
@required Map<String, dynamic> body,
FromJson<T> fromJson,
bool useFromJsonOnFailure = false,
Map<String, String> headers}) async {
try {
var response =
await http.post(url, headers: headers, body: jsonEncode(body));
return _handleResult(response, fromJson, useFromJsonOnFailure);
} catch (e, stack) {
Logger.logEvent(
'API fail: URL: $url, Error: ${e.toString()}',
exception: e,
stackTrace: stack,
);
return ApiResponse(-1, error: e.toString());
}
}
Future<ApiResponse<T>> postAsString<T>(
{@required String url,
@required String body,
FromJson<T> fromJson,
bool useFromJsonOnFailure = false,
Map<String, String> headers}) async {
try {
var response = await http.post(url, headers: headers, body: body);
return _handleResult(response, fromJson, useFromJsonOnFailure);
} catch (e, stack) {
Logger.logEvent(
'API fail: URL: $url, Error: ${e.toString()}',
exception: e,
stackTrace: stack,
);
return ApiResponse(-1, error: e.toString());
}
}
Future<ApiResponse<List<T>>> postAndGetList<T>(
{@required String url,
@required Map<String, dynamic> body,
@required FromJson<T> fromJson,
Map<String, String> headers}) async {
try {
var response =
await http.post(url, headers: headers, body: jsonEncode(body));
return _handleListResult(response, fromJson);
} catch (e, stack) {
Logger.logEvent(
'API fail: URL: $url, Error: ${e.toString()}',
exception: e,
stackTrace: stack,
);
return ApiResponse(-1, error: e.toString());
}
}
Future<ApiResponse<T>> put<T>(
{@required String url,
@required Map<String, dynamic> body,
FromJson<T> fromJson,
bool useFromJsonOnFailure = false,
Map<String, String> headers}) async {
try {
var response =
await http.put(url, headers: headers, body: jsonEncode(body));
return _handleResult(response, fromJson, useFromJsonOnFailure);
} catch (e, stack) {
Logger.logEvent(
'API fail: URL: $url, Error: ${e.toString()}',
exception: e,
stackTrace: stack,
);
return ApiResponse(-1, error: e.toString());
}
}
Future<ApiResponse<T>> putList<T>(
{@required String url,
@required List body,
FromJson<T> fromJson,
bool useFromJsonOnFailure = false,
Map<String, String> headers}) async {
try {
var response =
await http.put(url, headers: headers, body: jsonEncode(body));
return _handleResult(response, fromJson, useFromJsonOnFailure);
} catch (e, stack) {
Logger.logEvent(
'API fail: URL: $url, Error: ${e.toString()}',
exception: e,
stackTrace: stack,
);
return ApiResponse(-1, error: e.toString());
}
}
Future<ApiResponse<T>> delete<T>(
{@required String url, Map<String, String> headers}) async {
try {
var response = await http.delete(url, headers: headers);
return _handleResult(response, null, false);
} catch (e, stack) {
Logger.logEvent(
'API fail: URL: $url, Error: ${e.toString()}',
exception: e,
stackTrace: stack,
);
return ApiResponse(-1, error: e.toString());
}
}
ApiResponse<T> _handleResult<T>(http.Response response,
T Function(Map<String, dynamic>) fromJson, bool useFromJsonOnFailure) {
T data;
if (_isSuccessStatusCode(response.statusCode)) {
if (fromJson != null) {
data = fromJson(jsonDecode(response.body) as Map<String, dynamic>);
}
return ApiResponse<T>(response.statusCode, data: data);
} else {
if (fromJson != null && useFromJsonOnFailure) {
data = fromJson(jsonDecode(response.body) as Map<String, dynamic>);
}
Logger.logEvent(
'API fail: URL: ${response.request.url}, Error: ${response.body}');
return ApiResponse(response.statusCode, data: data, error: response.body);
}
}
ApiResponse<Uint8List> _handleByteArrayResult(http.Response response) {
Uint8List data;
if (_isSuccessStatusCode(response.statusCode)) {
data = response.bodyBytes;
return ApiResponse<Uint8List>(response.statusCode, data: data);
} else {
Logger.logEvent(
'API fail: URL: ${response.request.url}, Error: ${response.body}');
return ApiResponse(response.statusCode, data: data, error: response.body);
}
}
ApiResponse<List<T>> _handleListResult<T>(
http.Response response, T Function(Map<String, dynamic>) fromJson) {
if (_isSuccessStatusCode(response.statusCode)) {
var list = json.decode(response.body) as Iterable;
var data = list.map((x) => fromJson(x as Map<String, dynamic>)).toList();
return ApiResponse<List<T>>(response.statusCode, data: data);
} else {
Logger.logEvent(
'API fail: URL: ${response.request.url}, Error: ${response.body}');
return ApiResponse(response.statusCode, error: response.body);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment