Skip to content

Instantly share code, notes, and snippets.

@drejohnson
Created December 4, 2019 14:29
Show Gist options
  • Select an option

  • Save drejohnson/15a77fd5ad7e72495292669fee663707 to your computer and use it in GitHub Desktop.

Select an option

Save drejohnson/15a77fd5ad7e72495292669fee663707 to your computer and use it in GitHub Desktop.
type request;
type response;
type body;
type readyState =
| Unsent
| Opened
| HeadersReceived
| Loading
| Done
| Unknown;
let decodeReadyState =
fun
| 0 => Unsent
| 1 => Opened
| 2 => HeadersReceived
| 3 => Loading
| 4 => Done
| _ => Unknown;
type method =
| GET
| POST
| PUT
| DELETE;
[@bs.new] external makeXMLHttpRequest: unit => request = "XMLHttpRequest";
[@bs.get] external readyStateExternal: request => int = "readyState";
let readyState = (xhr: request) =>
decodeReadyState(xhr |> readyStateExternal);
[@bs.send]
external addEventListener: (request, string, unit => unit) => unit =
"addEventListener";
[@bs.send]
external setRequestHeader: (request, string, 'a) => unit = "setRequestHeader";
[@bs.get] external status: request => int = "status";
[@bs.get] external response: request => response = "response";
[@bs.get] external body: request => body = "body";
[@bs.send]
external open_:
(
request,
~method: string,
~url: string,
~async: bool=?,
~user: string=?,
~password: string=?,
unit
) =>
unit =
"open";
[@bs.send] external send: (request, option('a)) => unit = "send";
[@bs.send] external abort: request => unit = "abort";
[@bs.scope "JSON"] [@bs.val] external parseResponse: response => 'a = "parse";
[@bs.scope "JSON"] [@bs.val]
external stringifyBody: body => Js.Json.t = "stringify";
let xhr = makeXMLHttpRequest();
let fetch =
(
~url,
~method,
~body=?,
~headers=?,
~onSuccess: option('a),
// ~onFail: option('a),
(),
) => {
let httpMethod =
switch (method) {
| GET => "GET"
| POST => "POST"
| PUT => "PUT"
| DELETE => "DELETE"
};
let async =
switch (onSuccess) {
| Some(_) => true
| None => false
};
let processReqChange = () =>
switch (xhr->readyState) {
| Done =>
switch (xhr->status) {
| 200 =>
switch (onSuccess) {
| Some(onSuccess) => onSuccess(xhr->response->parseResponse)
| None => ()
}
| _ => xhr->abort
}
| _ => ()
};
xhr->addEventListener("load", () => processReqChange());
xhr->addEventListener("error", () => Js.log("Error"));
xhr->open_(~method=httpMethod, ~url, ~async, ());
switch (headers) {
| Some(headers) =>
headers
->Belt.List.map(header => {
let (k, v) = header;
xhr->setRequestHeader(k, v);
})
->ignore
| _ => ()
};
switch (body) {
| Some(body) => xhr->send(body)
| None => xhr->send(None)
};
};
let login = values => {
// set state or dispatch action ex. dispatch(Authenticating);
Jax.fetch(
~url="https://reqres.in/api/login",
~method=POST,
~body=Some(Js.Json.stringify(values)),
~headers=[("Content-Type", "application/json")],
~onSuccess=
Some(
res => {
let token = res##token;
// set state or dispatch action ex. dispatch(AuthSuccess(token));
},
), // continuation that returns response object
(),
);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment