Created
March 21, 2022 06:57
-
-
Save dev4jam/ce094af46be6150cd0d20322e37dd958 to your computer and use it in GitHub Desktop.
Full source code of the Network Service
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:freezed_annotation/freezed_annotation.dart'; | |
import 'dart:io'; | |
part 'NetworkRequestBody.freezed.dart'; | |
part 'NetworkResponse.freezed.dart'; | |
class AccessTokenResponse { | |
String? accessToken; | |
AccessTokenResponse.fromJson(Map<String, dynamic> json) { | |
accessToken = json['access_token']; | |
} | |
} | |
@freezed | |
class NetworkRequestBody with _$NetworkRequestBody { | |
const factory NetworkRequestBody.empty() = Empty; | |
const factory NetworkRequestBody.json(Map<String, dynamic> data) = Json; | |
const factory NetworkRequestBody.text(String data) = Text; | |
} | |
enum NetworkRequestType { GET, POST, PUT, PATCH, DELETE } | |
class NetworkRequest { | |
const NetworkRequest({ | |
required this.type, | |
required this.path, | |
required this.data, | |
this.queryParams, | |
this.headers, | |
}); | |
final NetworkRequestType type; | |
final String path; | |
final NetworkRequestBody data; | |
final Map<String, dynamic>? queryParams; | |
final Map<String, String>? headers; | |
} | |
@freezed | |
class NetworkResponse<Model> with _$NetworkResponse { | |
const factory NetworkResponse.ok(Model data) = Ok; | |
const factory NetworkResponse.invalidParameters(String message) = InvalidParameters; | |
const factory NetworkResponse.noAuth(String message) = NoAuth; //401 | |
const factory NetworkResponse.noAccess(String message) = NoAccess; //403 | |
const factory NetworkResponse.badRequest(String message) = BadRequest; //400 | |
const factory NetworkResponse.notFound(String message) = NotFound; //404 | |
const factory NetworkResponse.conflict(String message) = Conflict; //409 | |
const factory NetworkResponse.noData(String message) = NoData; //500 | |
} | |
class _PreparedNetworkRequest<Model> { | |
const _PreparedNetworkRequest( | |
this.request, | |
this.parser, | |
this.dio, | |
this.headers, | |
this.onSendProgress, | |
this.onReceiveProgress, | |
); | |
final NetworkRequest request; | |
final Model Function(Map<String, dynamic>) parser; | |
final Dio dio; | |
final Map<String, dynamic> headers; | |
final ProgressCallback? onSendProgress; | |
final ProgressCallback? onReceiveProgress; | |
} | |
Future<NetworkResponse<Model>> executeRequest<Model>( | |
_PreparedNetworkRequest request, | |
) async { | |
try { | |
dynamic body = request.request.data.whenOrNull( | |
json: (data) => data, | |
text: (data) => data, | |
); | |
final response = await request.dio.request( | |
request.request.path, | |
data: body, | |
queryParameters: request.request.queryParams, | |
options: Dio.Options( | |
method: request.request.type.name, | |
headers: request.headers, | |
), | |
onSendProgress: request.onSendProgress, | |
onReceiveProgress: request.onReceiveProgress, | |
); | |
return NetworkResponse.ok(request.parser(response.data)); | |
} on Dio.DioError catch (error) { | |
final errorText = error.toString(); | |
if (error.requestOptions.cancelToken!.isCancelled) { | |
return NetworkResponse.noData(errorText); | |
} | |
switch (error.response?.statusCode) { | |
case 400: | |
return NetworkResponse.badRequest(errorText); | |
case 401: | |
return NetworkResponse.noAuth(errorText); | |
case 403: | |
return NetworkResponse.noAccess(errorText); | |
case 404: | |
return NetworkResponse.notFound(errorText); | |
case 409: | |
return NetworkResponse.conflict(errorText); | |
default: | |
return NetworkResponse.noData(errorText); | |
} | |
} catch (error) { | |
return NetworkResponse.noData(error.toString()); | |
} | |
} | |
class NetworkService { | |
NetworkService({ | |
required this.baseUrl, | |
dioClient, | |
httpHeaders, | |
}) : this._dio = dioClient, | |
this._headers = httpHeaders ?? {}; | |
Dio? _dio; | |
final String baseUrl; | |
Map<String, String> _headers; | |
Future<Dio> _getDefaultDioClient() async { | |
_headers['content-type'] = 'application/json; charset=utf-8'; | |
final dio = Dio() | |
..options.baseUrl = baseUrl | |
..options.headers = _headers | |
..options.connectTimeout = 5000 // 5 seconds | |
..options.receiveTimeout = 3000; // 3 seconds | |
} | |
return dio; | |
} | |
void addBasicAuth(String accessToken) { | |
_headers['Authorization'] = 'Bearer $accessToken'; | |
} | |
Future<NetworkResponse<Model>> execute<Model>( | |
NetworkRequest request, | |
Model Function(Map<String, dynamic>) parser, { | |
ProgressCallback? onSendProgress = null, | |
ProgressCallback? onReceiveProgress = null, | |
}) async { | |
if (_dio == null) { | |
_dio = await _getDefaultDioClient(); | |
} | |
final req = _PreparedNetworkRequest<Model>( | |
request, | |
parser, | |
_dio!, | |
{..._headers, ...(request.headers ?? {})}, | |
onSendProgress, | |
onReceiveProgress, | |
); | |
final result = await compute( | |
executeRequest<Model>, | |
req, | |
); | |
return result; | |
} | |
} |
line 14 till line 19, what's happening there? also I'm getting an error after each "=" like : "The name 'Json' isn't a type and can't be used in a redirected constructor"
It's about freezed package which generate factory constructors initializers I think.
Same for NetworkResponse.
@AliJ91 yes, it's Freezed package annotation. Basically it creates states for your component. You can define them as classes as well.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
line 14 till line 19, what's happening there? also I'm getting an error after each "="
like : "The name 'Json' isn't a type and can't be used in a redirected constructor"