Skip to content

Instantly share code, notes, and snippets.

@fponticelli
Created April 4, 2016 02:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fponticelli/447f195d1f9abb2a0e770aaf38a4a719 to your computer and use it in GitHub Desktop.
Save fponticelli/447f195d1f9abb2a0e770aaf38a4a719 to your computer and use it in GitHub Desktop.
typed request
package bl.common;
using thx.promise.Promise;
import thx.Url;
import js.html.XMLHttpRequest;
import js.html.XMLHttpRequestResponseType;
class Request<T> {
public var response(default, null) : Promise<T>;
var request : XMLHttpRequest;
function new(response : Promise<T>, request : XMLHttpRequest) {
this.response = response;
this.request = request;
}
public function abort() {
request.abort();
return this;
}
public function onProgress(handler : Progress -> Void) {
request.addEventListener("progress", function(e) {
if(e.lengthComputable) {
handler(Step(e.loaded, e.total));
} else {
handler(Uncomputable);
}
});
return this;
}
public function map<Out>(f : T -> Out) : Request<Out>
return new Request(response.mapSuccess(f), request);
// static constructors
public static function getJson(url : Url) : Request<{}>
return get(url, RTJson);
public static function getText(url : Url) : Request<String>
return get(url, RTText);
public static function get<T>(url : Url, responseType : ResponseType<T>) : Request<T>
return make(Get, url, responseType);
public static function make<T>(method : Method, url : Url, responseType : ResponseType<T>) : Request<T> {
var request = new XMLHttpRequest();
var promise = Promise.create(function(resolve, reject) {
request.responseType = switch responseType {
case RTNone: NONE;
case RTArrayBuffer: ARRAYBUFFER;
case RTBlob: BLOB;
case RTDocument: DOCUMENT;
case RTJson: JSON;
case RTText: TEXT;
};
var methodAsString = switch method {
case Get: "GET";
};
request.open(methodAsString, url.toString());
request.addEventListener("load", function(e) {
trace(e);
if(request.status >= 500) {
trace("SERVER ERROR");
reject(new HttpServerError(request.status, request.statusText));
} else if(request.status >= 400) {
trace("CLIENT ERROR");
reject(new HttpClientError(request.status, request.statusText));
} else {
trace("LOAD");
resolve(request.response);
}
});
request.addEventListener("error", function(e) {
trace("ERROR");
trace(e);
reject(new HttpConnectionError(e.message));
});
request.addEventListener("abort", function(e) {
trace("ABORT");
reject(new HttpAbortError(url));
});
request.send();
});
return new Request(promise, request);
}
}
enum Method {
Get;
}
enum ResponseType<T> {
RTNone : ResponseType<thx.Nil>;
RTArrayBuffer : ResponseType<js.html.ArrayBuffer>;
RTBlob : ResponseType<js.html.Blob>;
RTDocument : ResponseType<js.html.Document>;
RTJson : ResponseType<{}>;
RTText : ResponseType<String>;
}
enum Progress {
Uncomputable;
Step(done : Float, total : Float);
}
class HttpAbortError extends thx.Error {
public function new(url : Url, ?pos : haxe.PosInfos) {
super('user aborted connection to $url', pos);
}
}
class HttpConnectionError extends thx.Error {}
class HttpStatusError extends thx.Error {
var statusCode(default, null) : Int;
var statusText(default, null) : String;
public function new(statusCode : Int, statusText : String, ?pos : haxe.PosInfos) {
this.statusCode = statusCode;
this.statusText = statusText;
super('$statusCode: $statusText', pos);
}
}
class HttpClientError extends HttpStatusError {}
class HttpServerError extends HttpStatusError {}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment