enableXhr method
Implementation
JavascriptRuntime enableXhr() {
httpClient = httpClient ?? http.Client();
dartContext[XHR_PENDING_CALLS_KEY] = [];
Timer.periodic(Duration(milliseconds: 40), (timer) {
// exits if there is no pending call to remote
if (!hasPendingXhrCalls()) return;
// collect the pending calls into a local variable making copies
List<dynamic> pendingCalls = List<dynamic>.from(getPendingXhrCalls()!);
// clear the global pending calls list
clearXhrPendingCalls();
// for each pending call, calls the remote http service
pendingCalls.forEach((element) async {
XhrPendingCall pendingCall = element as XhrPendingCall;
HttpMethod eMethod = HttpMethod.values.firstWhere((e) =>
e.toString().toLowerCase() ==
("HttpMethod.${pendingCall.method}".toLowerCase()));
late http.Response response;
switch (eMethod) {
case HttpMethod.head:
response = await httpClient!.head(
Uri.parse(pendingCall.url!),
headers: pendingCall.headers,
);
break;
case HttpMethod.get:
response = await httpClient!.get(
Uri.parse(pendingCall.url!),
headers: pendingCall.headers,
);
break;
case HttpMethod.post:
response = await httpClient!.post(
Uri.parse(pendingCall.url!),
body: (pendingCall.body is String)
? pendingCall.body
: jsonEncode(pendingCall.body),
headers: pendingCall.headers,
);
break;
case HttpMethod.put:
response = await httpClient!.put(
Uri.parse(pendingCall.url!),
body: (pendingCall.body is String)
? pendingCall.body
: jsonEncode(pendingCall.body),
headers: pendingCall.headers,
);
break;
case HttpMethod.patch:
response = await httpClient!.patch(
Uri.parse(pendingCall.url!),
body: (pendingCall.body is String)
? pendingCall.body
: jsonEncode(pendingCall.body),
headers: pendingCall.headers,
);
break;
case HttpMethod.delete:
response = await httpClient!.delete(
Uri.parse(pendingCall.url!),
headers: pendingCall.headers,
);
break;
}
// assuming request was successfully executed
String responseText = utf8.decode(response.bodyBytes);
try {
responseText = jsonEncode(json.decode(responseText));
} on Exception {}
final xhrResult = XmlHttpRequestResponse(
responseText: responseText,
responseInfo:
XhtmlHttpResponseInfo(statusCode: 200, statusText: "OK"),
);
final responseInfo = jsonEncode(xhrResult.responseInfo);
//final responseText = xhrResult.responseText; //.replaceAll("\\n", "\\\n");
final error = xhrResult.error;
// send back to the javascript environment the
// response for the http pending callback
this.evaluate(
"globalThis.xhrRequests[${pendingCall.idRequest}].callback($responseInfo, `$responseText`, $error);",
);
});
});
this.evaluate("""
var xhrRequests = {};
var idRequest = -1;
function XMLHttpRequestExtension_send_native() {
idRequest += 1;
var cb = arguments[4];
var context = arguments[5];
xhrRequests[idRequest] = {
callback: function(responseInfo, responseText, error) {
cb(responseInfo, responseText, error);
}
};
var args = [];
args[0] = arguments[0];
args[1] = arguments[1];
args[2] = arguments[2];
args[3] = arguments[3];
args[4] = idRequest;
sendMessage('SendNative', JSON.stringify(args));
}
""");
final evalXhrResult = this.evaluate(xhrJsCode);
if (_XHR_DEBUG) print('RESULT evalXhrResult: $evalXhrResult');
this.onMessage('SendNative', (arguments) {
try {
String? method = arguments[0];
String? url = arguments[1];
dynamic headersList = arguments[2];
String? body = arguments[3];
int? idRequest = arguments[4];
Map<String, String> headers = {};
headersList.forEach((header) {
// final headerMatch = regexpHeader.allMatches(value).first;
// String? headerName = headerMatch.group(0);
// String? headerValue = headerMatch.group(1);
// if (headerName != null) {
// headers[headerName] = headerValue ?? '';
// }
String headerKey = header[0];
headers[headerKey] = header[1];
});
(dartContext[XHR_PENDING_CALLS_KEY] as List<dynamic>).add(
XhrPendingCall(
idRequest: idRequest,
method: method,
url: url,
headers: headers,
body: body,
),
);
} on Error catch (e) {
if (_XHR_DEBUG) print('ERROR calling sendNative on Dart: >>>> $e');
} on Exception catch (e) {
if (_XHR_DEBUG) print('Exception calling sendNative on Dart: >>>> $e');
}
});
return this;
}