-
Notifications
You must be signed in to change notification settings - Fork 22
/
Main.elm
117 lines (86 loc) · 2.53 KB
/
Main.elm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
module Main exposing (Model, Msg(..), Repo, decoder, getRepos, init, main, repoDecoder, sendGet, subscriptions, update, url, view)
import Browser
import Debug
import Html exposing (Html, button, div, input, p, text)
import Html.Attributes exposing (value)
import Html.Events exposing (onClick, onInput)
import Http exposing (Error(..), Response, get)
import Json.Decode exposing (Decoder, field, int, string)
import Task
import Url.Builder as Url
main : Program () Model Msg
main =
Browser.element
{ view = view
, init = \() -> init
, update = update
, subscriptions = subscriptions
}
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.none
type alias Repo =
{ id : Int
, full_name : String
}
type alias Model =
{ query : String
, repos : List Repo
, error : Maybe Error
}
init : ( Model, Cmd Msg )
init =
( Model "evancz" [] Nothing, Cmd.none )
decoder : Decoder (List Repo)
decoder =
Json.Decode.list repoDecoder
repoDecoder : Decoder Repo
repoDecoder =
Json.Decode.map2 Repo
(field "id" int)
(field "full_name" string)
url : String -> String
url query =
Url.crossOrigin "https://api.github.com" [ "users", query, "repos" ] []
getRepos : String -> Cmd Msg
getRepos query =
sendGet LoadRepos (url query) decoder
type Msg
= UpdateQuery String
| Search
| LoadRepos (Result Http.Error (List Repo))
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
UpdateQuery value ->
( { model | query = value }, Cmd.none )
Search ->
( model, getRepos model.query )
LoadRepos maybeRepos ->
case maybeRepos of
Ok repos ->
( { model | repos = repos }, Cmd.none )
Err err ->
( { model | repos = [], error = Just err }, Cmd.none )
sendGet : (Result Error a -> msg) -> String -> Decoder a -> Cmd msg
sendGet msg theUrl theDecoder =
Http.get theUrl theDecoder
|> Http.send msg
view : Model -> Html Msg
view model =
div []
[ input
[ onInput UpdateQuery, value model.query ]
[]
, button [ onClick Search ] [ text "Search" ]
, div
[]
(List.map (\{ full_name } -> p [] [ text full_name ]) model.repos)
, text
(case model.error of
Nothing ->
""
Just error ->
"Error: " ++ Debug.toString error
)
]