request method

  1. @override
Future<void> request({
  1. R? requestModel,
})
override

ServiceResponseHandler callbacks will be used to handle the different possible responses from the request

Implementation

@override
Future<void> request({R? requestModel}) async {
  if (await Locator().connectivity.getConnectivityStatus() ==
      ConnectivityStatus.offline) {
    _handler.onNoConnectivity();
    return;
  }

  Map<String, dynamic> requestJson = {};
  if (requestModel != null) {
    requestJson = requestModel.toJson();
    if (!isRequestModelJsonValid(requestJson)) {
      _handler.onInvalidRequest(requestJson);
      return;
    }
  }

  if (RegExp(r'{(\w+)}').hasMatch(path) && requestModel == null) {
    // If a service has a variable in the path, request data is required
    _handler.onInvalidRequest(null);
    return;
  }

  final pathUri = Uri.parse(path);

  final injectedQueryParams = pathUri.queryParameters.map(
    (k, v) => MapEntry(
      k,
      _isVariable(v) ? requestJson[_removeWrapper(v)]?.toString() : v,
    ),
  );
  if (injectedQueryParams.containsValue(null)) {
    // Some query parameter variables where not substituted by request fields
    _handler.onInvalidRequest(requestJson);
    return;
  }

  var _pathSubstitutionSuccess = true;
  final injectedPath = pathUri.path.replaceAllMapped(
    RegExp(r'%7B(\w+)%7D'),
    (match) {
      final value = requestJson[match.group(1)];
      if (value == null) _pathSubstitutionSuccess = false;
      return value?.toString() ?? '';
    },
  );
  if (!_pathSubstitutionSuccess) {
    // Some path segment variables where not substituted by request fields
    _handler.onInvalidRequest(requestJson);
    return;
  }

  _resolvedPath = Uri(
    path: injectedPath,
    queryParameters: injectedQueryParams.isEmpty ? null : injectedQueryParams,
  ).toString();

  final response = await _restApi.request(
    method: _method,
    path: _resolvedPath!,
    requestBody: requestJson,
  );

  if (response.type == RestResponseType.timeOut) {
    _handler.onNoConnectivity();
    return;
  } else if (response.type != RestResponseType.success) {
    if (!onError(response, _handler)) {
      _handler.onError(response.type, response.content.toString());
      return;
    }
  }

  S model;

  try {
    final content = response.content.toString();
    final Map<String, dynamic> jsonResponse =
        (content.isEmpty) ? {} : json.decode(content) ?? <String, dynamic>{};
    model = parseResponse(jsonResponse);
  } on Error catch (e) {
    Locator().logger.debug('JsonService response parse error', e.toString());
    _handler.onInvalidResponse(response.content.toString());
    return;
  } on Exception catch (e) {
    Locator()
        .logger
        .debug('JsonService response parse exception', e.toString());
    _handler.onInvalidResponse(response.content.toString());
    return;
  }

  _handler.onSuccess(model);
}