sendRequest<R> method
FutureOr<R?>
sendRequest<R>(
- Uri uri, {
- DataRequestMethod method = DataRequestMethod.GET,
- Map<
String, String> ? headers, - bool omitDefaultParams = false,
- DataRequestType requestType = DataRequestType.adhoc,
- String? key,
- String? body,
- OnRawData<
R> ? onSuccess, - OnDataError<
R> ? onError,
inherited
The function used to perform an HTTP request and return an R
.
IMPORTANT:
uri
takes the FULLUri
including query parametersheaders
does NOT include ANY defaults such as defaultHeaders (unless you omit the argument, in which case defaults will be included)
Example:
await sendRequest(
baseUrl.asUri + 'token' & await defaultParams & {'a': 1},
headers: await defaultHeaders & {'a': 'b'},
onSuccess: (data) => data['token'] as String,
);
ignore: comment_references
To build the URI you can use String.asUri
, Uri.+
and Uri.&
.
To merge headers and params with their defaults you can use the helper
Map<String, dynamic>.&
.
In addition, onSuccess
is supplied to post-process the
data in JSON format. Deserialization and initialization
typically occur in this function.
onError
can also be supplied to override _RemoteAdapter.onError
.
Implementation
@override
FutureOr<R?> sendRequest<R>(
final Uri uri, {
DataRequestMethod method = DataRequestMethod.GET,
Map<String, String>? headers,
bool omitDefaultParams = false,
DataRequestType requestType = DataRequestType.adhoc,
String? key,
String? body,
OnRawData<R>? onSuccess,
OnDataError<R>? onError,
}) async {
// default key to type#s3mth1ng
final offlineKey = key ?? DataHelpers.generateKey(internalType);
assert(offlineKey.startsWith(internalType));
// execute request
return await super.sendRequest<R>(
uri,
method: method,
headers: headers,
requestType: requestType,
omitDefaultParams: omitDefaultParams,
key: key,
body: body,
onSuccess: (data) {
// remove all operations with this
// requestType/offlineKey metadata
OfflineOperation<T>(
requestType: requestType,
offlineKey: offlineKey,
request: '${method.toShortString()} $uri',
body: body,
headers: headers,
onSuccess: onSuccess,
onError: onError,
adapter: this,
).remove();
// yield
return onSuccess?.call(data);
},
onError: (e) {
if (isNetworkError(e.error)) {
// queue a new operation if this is
// a network error and we're offline
OfflineOperation<T>(
requestType: requestType,
offlineKey: offlineKey,
request: '${method.toShortString()} $uri',
body: body,
headers: headers,
onSuccess: onSuccess,
onError: onError,
adapter: this,
).add();
// wrap error in an OfflineException
e = OfflineException(error: e.error);
// call error handler but do not return it
(onError ?? this.onError).call(e);
// instead return a fallback model
switch (requestType) {
case DataRequestType.findAll:
return findAll(remote: false, syncLocal: false) as Future<R>;
case DataRequestType.findOne:
case DataRequestType.save:
// call without type (ie 3 not users#3)
// key! as we know findOne does pass it
return findOne(key!.detypify(), remote: false) as Future<R?>;
default:
return null;
}
}
// if it was not a network error
// remove all operations with this
// requestType/offlineKey metadata
OfflineOperation<T>(
requestType: requestType,
offlineKey: offlineKey,
request: '${method.toShortString()} $uri',
body: body,
headers: headers,
onSuccess: onSuccess,
onError: onError,
adapter: this,
).remove();
// return handler call
return (onError ?? this.onError).call(e);
},
);
}