Skip to content

Instantly share code, notes, and snippets.

@ultrox
Last active August 9, 2023 20:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ultrox/89f188a72b909e3a69c94c446f7e25ea to your computer and use it in GitHub Desktop.
Save ultrox/89f188a72b909e3a69c94c446f7e25ea to your computer and use it in GitHub Desktop.
Elm 0.19.1 + RemoteData. How to use RemoteDetails talk from Kris Jenkins - Slaying a UI antypattern
module Main exposing (..)
-- This code needs following dependencies:
-- elm/browser 1.0.2
-- elm/html 1.0.0
-- elm/http 2.0.0
-- elm/json 1.1.3
-- elm/random 1.0.0
-- krisajenkins/remotedata 6.0.1
-- NoRedInk/elm-json-decode-pipeline/ 1.0.1
-- Can try it here: https://ellie-app.com/nBCdHpv2jRta1
-- Watch video: https://www.youtube.com/watch?v=NLcRzOyrH08
-- https://github.com/krisajenkins/remotedata/blob/master/src/RemoteData.elm
import Browser
import Html exposing (Html, br, div, input, text)
import Html.Attributes exposing (type_, value)
import Html.Events exposing (onClick)
import Http exposing (get)
import Json.Decode exposing (Decoder, string)
import Json.Decode.Pipeline exposing (required)
import Random exposing (generate, int)
import RemoteData exposing (RemoteData(..), WebData, asCmd, fromTask)
import Task exposing (Task, andThen, attempt, perform)
type alias Person =
{ name : String
, gender : String
}
type alias Starship =
{ name : String
, model : String
}
type alias Model =
{ person : WebData Person
, starship : WebData Starship
, counter : Int
}
type Msg
= PersonResponse (WebData Person)
| StarshipResponse (WebData Starship)
| GenerateRandomNumber
| NewNumber Int
decodePerson : Decoder Person
decodePerson =
Json.Decode.succeed Person
|> required "name" string
|> required "gender" string
decodeStarship : Decoder Starship
decodeStarship =
Json.Decode.succeed Starship
|> required "name" string
|> required "model" string
getPerson : Int -> Cmd Msg
getPerson id =
Http.get
{ url = "https://swapi.dev/api/people/" ++ String.fromInt id
, expect = Http.expectJson (RemoteData.fromResult >> PersonResponse) decodePerson
}
getStarship : Int -> Cmd Msg
getStarship id =
Http.get
{ url = "https://swapi.dev/api/starships/" ++ String.fromInt id
, expect = Http.expectJson (RemoteData.fromResult >> StarshipResponse) decodeStarship
}
randomIdGenerator : Random.Generator Int
randomIdGenerator =
int 1 100
init : () -> ( Model, Cmd Msg )
init _ =
( { person = Loading
, starship = NotAsked
, counter = 1
}
, getPerson 1
)
generateRandomNumberCmd : Cmd Msg
generateRandomNumberCmd =
Task.succeed 1
|> Task.perform NewNumber
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
NewNumber newNumber ->
( { model
| counter = newNumber
, person = Loading
, starship = Loading
}
, getPerson newNumber
)
GenerateRandomNumber ->
( model, generateRandomNumberCmd )
PersonResponse response ->
( { model
| person = response
, starship = Loading
}
, getStarship 9
)
StarshipResponse response ->
( { model | starship = response }, Cmd.none )
view : Model -> Html Msg
view model =
case model.person of
NotAsked ->
viewPerson model "Initializing: "
Loading ->
viewPerson model "Loading: "
Failure err ->
viewPerson model ("Error: " ++ Debug.toString err)
Success news ->
viewPerson model ""
viewPerson : Model -> String -> Html Msg
viewPerson model error =
div []
[ text error
, text (Debug.toString model.person)
, br [] []
, text (Debug.toString model.starship)
, Html.p []
[ input
[ onClick GenerateRandomNumber
, type_ "button"
, value "Get Person"
]
[]
]
]
main =
Browser.element
{ init = init
, update = update
, subscriptions = always Sub.none
, view = view
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment