Skip to content

Instantly share code, notes, and snippets.

@curtiswilkinson
Created July 12, 2017 12:04
Show Gist options
  • Save curtiswilkinson/659f5d6d0bd8a1c894a867d384919ec6 to your computer and use it in GitHub Desktop.
Save curtiswilkinson/659f5d6d0bd8a1c894a867d384919ec6 to your computer and use it in GitHub Desktop.
Get Users with paging: https://ellie-app.com/3JSh7Jkb3Bma1/5
module Main exposing (..)
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)
import Http
import Json.Decode as Decode
type alias Model =
{ users : List User
, page : Int
}
type alias User =
{ id : Int
, first_name : String
, last_name : String
, avatar : String
}
main : Program Never Model Msg
main =
Html.program
{ init = init
, update = update
, view = view
, subscriptions = subscriptions
}
init : ( Model, Cmd Msg )
init =
( Model [] 1, getUserList 1 )
type Msg
= Next
| Prev
| GetUserList
| UserListResponse (Result Http.Error (List User))
shiftPage : Model -> Int -> ( Model, Cmd Msg )
shiftPage model shift =
( { model | page = model.page + shift }, getUserList (model.page + shift) )
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
Next ->
shiftPage model 1
Prev ->
shiftPage model (-1)
GetUserList ->
( model, getUserList model.page )
UserListResponse (Ok users) ->
( { model | users = users }, Cmd.none )
UserListResponse (Err _) ->
( model, Cmd.none )
displayUser : User -> Html Msg
displayUser user =
div [ style styles.wrapper ]
[ img [ style styles.image, src user.avatar ] []
, div [ style styles.details ]
[ p []
[ strong [] [ text "User ID: " ]
, text (toString user.id)
]
, p []
[ strong [] [ text "Name: " ]
, text (user.first_name ++ " " ++ user.last_name)
]
]
]
view : Model -> Html Msg
view model =
div []
[ div [] (List.map displayUser model.users)
, div [ style styles.buttonRow ]
[ button [ onClick Prev, style (( "float", "left" ) :: styles.button) ]
[ text "Prev" ]
, span
[ style [ ( "margin-top", "8px" ), ( "display", "inline-block" ) ] ]
[ strong [] [ text "Page: " ]
, text (toString model.page)
]
, button [ onClick Next, style (( "float", "right" ) :: styles.button) ]
[ text "Next" ]
]
]
getUserList : Int -> Cmd Msg
getUserList page =
let
url =
"https://reqres.in/api/users?page=" ++ (toString page)
in
Http.send UserListResponse (Http.get url decodeUserList)
decodeUserList : Decode.Decoder (List User)
decodeUserList =
Decode.at [ "data" ] (Decode.list decodeUser)
decodeUser : Decode.Decoder User
decodeUser =
Decode.map4
User
(Decode.at [ "id" ] Decode.int)
(Decode.at [ "first_name" ] Decode.string)
(Decode.at [ "last_name" ] Decode.string)
(Decode.at [ "avatar" ] Decode.string)
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.none
shadow =
( "box-shadow", "0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23)" )
styles =
{ wrapper =
[ ( "clear", "both" )
, ( "padding", "10px" )
, ( "margin", "5px" )
, ( "float", "left" )
, ( "width", "100%" )
, ( "max-width", "300px" )
, shadow
]
, image =
[ ( "float", "left" )
, shadow
]
, button =
[ ( "width", "100px" )
, ( "padding", "10px" )
, ( "text-transform", "uppercase" )
, ( "color", "white" )
, ( "background-color", "#333" )
, ( "border", "none" )
]
, buttonRow =
[ ( "max-width", "320px" )
, ( "margin", "5px" )
, ( "text-align", "center" )
]
, details =
[ ( "float", "left" )
, ( "padding-left", "10px" )
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment