-
Notifications
You must be signed in to change notification settings - Fork 0
/
PlayHTTP.elm
252 lines (182 loc) · 5.91 KB
/
PlayHTTP.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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
module PlayHTTP exposing (..)
import Html exposing (..)
import Html.Attributes exposing (class, id)
import Html.Events exposing (onClick)
import Http
import Debug
import Json.Decode as JSONDecode exposing (Decoder)
import Json.Decode.Pipeline exposing (decode, required, optional, hardcoded)
-- MODEL
type alias Model =
{}
-- VIEW
view : Model -> Html Msg
view model =
div [ class "page-content" ]
[ h1 [] [ text "elm-http-request" ]
, button [ onClick Call_getStringRequest ] [ text "Call_getStringRequest" ]
, br [] []
, button [ onClick Call_getStringRequest2 ] [ text "Call_getStringRequest2" ]
, br [] []
, button [ onClick Call_getStringRequest3 ] [ text "Call_getStringRequest3" ]
, br [] []
, button [ onClick Call_FailGetStringRequest ] [ text "Call_FailGetStringRequest" ]
, br [] []
, button [ onClick Call_GetUser ] [ text "Call_GetUser" ]
]
-- Update
type Msg
= NoOp
| Call_getStringRequest
| Call_getStringRequest2
| Call_getStringRequest3
| Handle_getStringRequest (Result Http.Error String)
| Call_FailGetStringRequest
| Handle_FailGetStringRequest (Result Http.Error String)
| Call_GetUser
| Handle_GetUser (Result Http.Error User)
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
NoOp ->
( model, Cmd.none )
-- call the getStringRequest command, which will pass the request to the Runtime
-- model remains unchanged
Call_getStringRequest ->
model ! [ getStringRequest ]
Call_getStringRequest2 ->
model ! [ getStringRequest2 ]
Call_getStringRequest3 ->
model ! [ getStringRequest3 ]
-- Http.send will invoke this Msg passing the response or error
Handle_getStringRequest (Ok result) ->
model ! []
Handle_getStringRequest (Err errorMessage) ->
-- log the error message to the console
Debug.log (toString errorMessage) model ! []
Call_FailGetStringRequest ->
model ! [ failGetStringRequest ]
Handle_FailGetStringRequest (Ok result) ->
model ! []
Handle_FailGetStringRequest (Err errorMessage) ->
-- log the error message to the console
Debug.log (httpErrorToString errorMessage) model ! []
Call_GetUser ->
model ! [ getUser ]
Handle_GetUser (Ok result) ->
model ! []
Handle_GetUser (Err errorMessage) ->
Debug.log (httpErrorToString errorMessage) model ! []
-- HTTP Requests
serverURL : String
serverURL =
"http://localhost:3000"
getStringRequest : Cmd Msg
getStringRequest =
let
request =
Http.getString serverURL
in
Http.send Handle_getStringRequest request
getStringRequest2 : Cmd Msg
getStringRequest2 =
{-
Similar request to getStringRequest but uses the Http.get function
Http.get expects a decoder, in this case it's a string, so we use the "string" helper.
An important thing to be aware with Http.get is that unlike getString, it expects a JSON response.
If the response does not match a decoder, Elm will return an Http.BadPayload error.
-}
let
-- The response must be a quoted string `"foo"` for example.
-- If the string is not quoted, the decoder fails since it's not JSON.
decoder =
JSONDecode.string
request =
Http.get serverURL decoder
in
Http.send Handle_getStringRequest request
getStringRequest3 : Cmd Msg
getStringRequest3 =
{-
same request as getStringRequest but uses the lower level Http.request function
to build the http request.
Here we went back to expecting a string.
-}
let
request =
Http.request
{ method = "GET"
, headers = []
, url = serverURL
, body = Http.emptyBody
, expect = Http.expectString
, timeout = Nothing
, withCredentials = False
}
in
Http.send Handle_getStringRequest request
failGetStringRequest : Cmd Msg
failGetStringRequest =
{- similar to all the other requests, but this time it will fail -}
let
decoder =
JSONDecode.string
request =
Http.request
{ method = "GET"
, headers = []
, url = serverURL ++ "/fail_500"
, body = Http.emptyBody
, expect = Http.expectJson decoder
, timeout = Nothing
, withCredentials = False
}
in
Http.send Handle_FailGetStringRequest request
httpErrorToString : Http.Error -> String
httpErrorToString error =
case error of
Http.Timeout ->
"Timeout!"
Http.NetworkError ->
"Network Error"
Http.BadPayload status message ->
"status: " ++ (toString status) ++ " " ++ (toString message)
Http.BadStatus status ->
"status: " ++ (toString status)
Http.BadUrl status ->
"status: " ++ (toString status)
type alias User =
{ name : String
, age : Int
}
userDecoder : Decoder User
userDecoder =
decode User
|> required "name" JSONDecode.string
|> required "age" JSONDecode.int
getUser : Cmd Msg
getUser =
let
userURL =
serverURL ++ "/user/1"
request =
Http.get userURL userDecoder
in
Http.send Handle_GetUser request
-- MAIN
initialModel =
{}
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.none
init =
( initialModel, Cmd.none )
main : Program Never Model Msg
main =
Html.program
{ init = init
, view = view
, update = update
, subscriptions = subscriptions
}