remote_data for Gleam

This package is inspired on the Elm package RemoteData.

Package Version Hex Docs

Installation

gleam add remote_data

Usage

This example shows how to use the remote_data package in a lustre application.

First you wrap the data you want to fetch in a RemoteData type:

import remote_data.{type RemoteData} as rd
import lustre
import lustre/element
import lustre/element/html
import lustre_http.{type HttpError}

// MODEL -----------------------------------------------------------------------

type Model {
 Model(quote: RemoteData(Quote, HttpError))
}

type Quote {
 Quote(author: String, content: String)
}

Initialize the model with rd.NotAsked:

fn init(_) -> #(Model, Effect(Msg)) {
 #(Model(quote: rd.NotAsked), effect.none())
}

When you want to fetch data, you can use the rd.Loading constructor to indicate that the data is being fetched. When the data is fetched, you can use the rd.from_result to convert the Result to a RemoteData type:

pub opaque type Msg {
 UserClickedRefresh
 ApiUpdatedQuote(Result(Quote, HttpError))
}

fn update(model: Model, msg: Msg) -> #(Model, Effect(Msg)) {
 case msg {
   UserClickedRefresh -> #(Model(quote: rd.Loading), get_quote())
   ApiUpdatedQuote(quote) -> #(Model(quote: rd.from_result(quote)), effect.none())
 }
}

fn get_quote() -> Effect(Msg) {
 let url = "https://api.quotable.io/random"
 let decoder =
   dynamic.decode2(
     Quote,
     dynamic.field("author", dynamic.string),
     dynamic.field("content", dynamic.string),
   )

 lustre_http.get(url, lustre_http.expect_json(decoder, ApiUpdatedQuote))
}

Finally, you can pattern match on the RemoteData type to display the data in the view:

fn view_quote(quote: RemoteData(Quote, HttpError)) -> Element(msg) {
 case quote {
   rd.Success(quote) ->
     html.div([], [
       element.text(quote.author <> " once said..."),
       html.p([attribute.style([#("font-style", "italic")])], [
         element.text(quote.content),
       ]),
     ])
   rd.NotAsked -> html.p([], [element.text("Click the button to get a quote!")])
   rd.Loading -> html.p([], [element.text("Fetching quote...")])
   rd.Failure(_) -> html.p([], [element.text("Failed to fetch quote!")])
 }
}

Further documentation can be found at https://hexdocs.pm/remote_data.

Search Document