http4s
These examples demonstrate how to integrate with http4s-dom.
libraryDependencies += "org.http4s" %%% "http4s-dom" % "0.2.11"
HTTP Request
import calico.html.io.{*, given}
import calico.syntax.*
import calico.unsafe.given
import cats.effect.*
import cats.syntax.all.*
import fs2.Stream
import fs2.concurrent.*
import fs2.dom.*
import io.circe.*
import org.http4s.*
import org.http4s.circe.*
import org.http4s.dom.*
case class Repo(stargazers_count: Int) derives Decoder
object Repo:
given EntityDecoder[IO, Repo] = jsonOf
val client = FetchClientBuilder[IO].create
val app: Resource[IO, HtmlDivElement[IO]] = (
input(size := 36, typ := "text", value := "armanbilge/calico"),
SignallingRef[IO].of("").toResource
).flatMapN { (repoInput, starsResult) =>
val countStars: IO[Unit] =
starsResult.set(" counting ... ") *>
repoInput.value.get
.flatMap { repo =>
client.expect[Repo](s"https://api.github.com/repos/$repo").attempt
}
.flatMap {
case Right(Repo(stars)) => starsResult.set(s"$stars ★")
case Left(_) => starsResult.set(s"Not found :(")
}
div(
h3("How many stars?"),
repoInput,
button(
// switchMap cancels an ongoing request if the button is clicked again
onClick --> (_.switchMap(_ => Stream.exec(countStars))),
"Count"
),
span(
styleAttr := "margin-left: 1em; color: var(--secondary-color)",
starsResult
)
)
}
app.renderInto(node.asInstanceOf[fs2.dom.Node[IO]]).useForever.unsafeRunAndForget()