Last active
July 14, 2020 06:39
-
-
Save toan2406/c160af8bea2576a138b3ac64e4f04551 to your computer and use it in GitHub Desktop.
A Post component which fetches and displays title
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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