Skip to content

Instantly share code, notes, and snippets.

@toan2406
Last active July 14, 2020 06:39
Show Gist options
  • Save toan2406/c160af8bea2576a138b3ac64e4f04551 to your computer and use it in GitHub Desktop.
Save toan2406/c160af8bea2576a138b3ac64e4f04551 to your computer and use it in GitHub Desktop.
A Post component which fetches and displays title
open Relude.Globals;
module R = Relude;
let (>>=) = IO.(>>=);
let fetchPostById: string => IO.t(string, string) =
id =>
Fetch.fetch("https://jsonplaceholder.typicode.com/posts/" ++ id)
|> Js.Promise.then_(Fetch.Response.text)
|> RJs.Promise.toIO
|> IO.mapError(_ => "Failed to fetch user with ID " ++ id);
let parseJson: string => IO.t(Js.Json.t, string) =
str =>
IO.tries(() => Js.Json.parseExn(str))
|> IO.mapError(_ => "Failed to parse JSON");
let decodeTitle: Js.Json.t => IO.t(string, string) =
json =>
Js.Json.decodeObject(json)
|> R.Option.flatMap(obj => Js.Dict.get(obj, "title"))
|> R.Option.flatMap(title => Js.Json.decodeString(title))
|> IO.fromOption(() => "Failed to parse title");
[@react.component]
let make = (~postId: string) => {
let (result, setResult) = React.useState(_ => "Please wait...");
// IO is lazy evaluated
let doStuffsIO: IO.t(string, string) =
postId
|> IO.pure
>>= fetchPostById
>>= parseJson
>>= decodeTitle
|> IO.tap(v => Js.log2("Log:", v));
React.useEffect1(
() => {
doStuffsIO
|> IO.unsafeRunAsync(
fun
| Belt.Result.Ok(content) => setResult(_ => content)
| Belt.Result.Error(error) => setResult(_ => error),
);
None;
},
[||],
);
<div> result->React.string </div>;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment