Unavailable. Nobody can download this version any more, with elm or with the Lamdera compiler: github.com/opvasger/loadable is gone (deleted or private); Software Heritage not asked yet (this run's --swh-calls were used up); no fork with tag 3.0.0 found (31 same-name repos checked); no cached copy. Use another version.
Intuitive data-loading in Elm!
This project is an extension of the ideas from a very cool project/blog/talk!
User-interfaces (I like) usually view initial-loads and reloads differently. Stale information can be viewed in cases where you are reloading a value or failed to.
This is the type at the core of the module:
type Loadable error value
= Idle
| Loading
| Success value
| Failure error
| Reloading value
| ReloadFailure error valueThis complete Elm-program shows how loading (and displaying) a github-repository could be done:
module Main exposing (main)
import Browser
import Element exposing (el)
import Element.Font
import Element.Input
import Http
import Json.Decode
import Loadable
type alias Model =
{ repository : Loadable.FromHttp Repository }
type Msg
= GetRepository
| GotRepository (Result Http.Error Repository)
init _ =
( { repository = Loadable.Idle }
, Cmd.none
)
update msg model =
case msg of
GetRepository ->
( { model | repository = Loadable.expectUpdate model.repository }
, getRepository
)
GotRepository result ->
( { model | repository = Loadable.update result model.repository }
, Cmd.none
)
view model =
Element.layout [] <|
el [ Element.centerX, Element.centerY, Element.spacing 10 ]
(viewLoadable "repository" viewRepository model.repository)
main : Program () Model Msg
main =
Browser.element
{ init = init
, view = view
, update = update
, subscriptions = always Sub.none
}
type alias Repository =
{ name : String
, description : String
, language : String
}
viewRepository repo =
Element.column [ Element.paddingXY 0 10 ]
[ el [ Element.Font.bold ] (Element.text repo.name)
, el [ Element.Font.italic ] (Element.text repo.description)
, Element.text ("written in " ++ repo.language)
]
getRepository =
Http.get
{ url = "https://api.github.com/repos/opvasger/loadable"
, expect = Http.expectJson GotRepository repositoryDecoder
}
repositoryDecoder =
Json.Decode.map3 Repository
(Json.Decode.field "name" Json.Decode.string)
(Json.Decode.field "description" Json.Decode.string)
(Json.Decode.field "language" Json.Decode.string)
viewGetRepositoryButton text =
Element.Input.button [ Element.Font.underline ]
{ onPress = Just GetRepository
, label = Element.text text
}
viewLoadable name viewValue loadable =
case loadable of
Loadable.Idle ->
viewGetRepositoryButton ("get the " ++ name)
Loadable.Loading ->
Element.text "loading"
Loadable.Success value ->
Element.column []
[ viewValue value
, viewGetRepositoryButton "reload"
]
Loadable.Failure _ ->
Element.column []
[ Element.text ("failed to get the " ++ name)
, viewGetRepositoryButton "retry"
]
Loadable.Reloading value ->
Element.column []
[ viewValue value
, Element.text "reloading..."
]
Loadable.ReloadFailure _ value ->
Element.column []
[ Element.text ("failed to reload the " ++ name)
, viewValue value
, viewGetRepositoryButton "retry"
]