An Introduction to Elm Series: Solution to ‘HTTP’ example 5


In the http://guide.elm-lang.org/architecture/effects/http.html, we were given a sample that loads random images from a web application on another service thought HTTP requests.

We were asked to print the error message of the request (if any) and update the UI to allow changing the topic (a parameter of the web call) either through an input field or a drop down list.

We wrote a message that accepts as string the new topic, that message is used both in the case of the input and in the case of the select list. Finally, we made sure that the ‘Please Wait’ image is shown while loading the new image from the remote server. The path for the ‘Please Wait’ image was added to a custom function to emulate a public static string value.

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
import Html exposing (..)
import Html.App as Html
import Html.Attributes exposing (..)
import Html.Events exposing (..)
import Http
import Json.Decode as Json
import Task
 
 
 
main =
  Html.program
    { init = init "cats"
    , view = view
    , update = update
    , subscriptions = subscriptions
    }
 
 
 
-- MODEL
 
 
type alias Model =
  { topic : String
  , gifUrl : String
  , error : String
  }
 
waitingImage : String
waitingImage =
  "5-http/waiting.png"
 
init : String -> (Model, Cmd Msg)
init topic =
  ( Model topic waitingImage ""
  , getRandomGif topic
  )
 
 
 
-- UPDATE
 
 
type Msg
  = MorePlease
  | FetchSucceed String
  | FetchFail Http.Error
  | NewTopic String
 
 
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
  case msg of
    MorePlease ->
      ({ model | gifUrl = waitingImage }, getRandomGif model.topic)
 
    FetchSucceed newUrl ->
      (Model model.topic newUrl "", Cmd.none)
 
    FetchFail error ->
      (Model model.topic waitingImage (toString error), Cmd.none)
 
    NewTopic newTopic ->
      ({ model | topic = newTopic }, Cmd.none)
 
 
-- VIEW
 
 
view : Model -> Html Msg
view model =
  div []
    [ h2 [] [text model.topic]
    , input [ type' "text", placeholder "Topic", onInput NewTopic ] []
    , select [ onInput NewTopic ]
      [ option [] [ text "Pokemon" ]
      , option [] [ text "SuperCars" ]
      , option [] [ text "Cyprus" ]
      , option [] [ text "Cats" ]
      , option [] [ text "Dogs" ]
     ; ]
    , button [ onClick MorePlease ] [ text "More Please!" ]
    , br [] []
    , img [src model.gifUrl] []
    , br [] []
    , div [] [text model.error]
   ; ]
 
 
 
-- SUBSCRIPTIONS
 
 
subscriptions : Model -> Sub Msg
subscriptions model =
  Sub.none
 
 
 
-- HTTP
 
 
getRandomGif : String -> Cmd Msg
getRandomGif topic =
  let
    url =
      "//api.giphy.com/v1/gifs/random?api_key=dc6zaTOxFJmzC&tag=" ++ topic
  in
    Task.perform FetchFail FetchSucceed (Http.get decodeGifUrl url)
 
 
decodeGifUrl : Json.Decoder String
decodeGifUrl =
  Json.at ["data", "image_url"] Json.string

You can download the solution from here [download id=”1811″]

This post is also available in: Αγγλικα

Απάντηση

This site uses Akismet to reduce spam. Learn how your comment data is processed.