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
|
module Catalog exposing (..)
import Browser
import Browser.Navigation as Nav
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)
import Http
import Json.Decode as D
import Json.Encode as Encode
import Url
import Url.Parser as P exposing ((</>), Parser, int, oneOf, s, string)
type alias Product =
{ id : Int
, name : String
, kind : Maybe String
, price : Float
, description : Maybe String
}
type alias Model =
{ pageStatus : Status
, products : List Product
}
type Status
= Loading
| Loaded
| NotLoaded
type Msg
= ProductsLoaded (Result Http.Error (List Product))
| FetchProducts
init : Model
init =
Model NotLoaded []
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
ProductsLoaded res ->
case res of
Ok s ->
( { model | products = s, pageStatus = Loaded }, Cmd.none )
Err e ->
let
_ =
Debug.log "error" e
in
( { model | pageStatus = NotLoaded }, Cmd.none )
FetchProducts ->
( { model | pageStatus = Loading }, fetchProducts )
decodeProduct : D.Decoder Product
decodeProduct =
D.map5 Product
(D.field "id" D.int)
(D.field "name" D.string)
(D.field "kind" (D.nullable D.string))
(D.field "price" D.float)
(D.field "description" (D.nullable D.string))
decodeResponse : D.Decoder (List Product)
decodeResponse =
D.list decodeProduct
fetchProducts : Cmd Msg
fetchProducts =
let
_ =
Debug.log "err" "fetching products"
in
Http.get
{ url = "http://127.0.0.1:7878/product/catalog"
, expect = Http.expectJson ProductsLoaded decodeResponse
}
viewStatus : Status -> String
viewStatus s =
case s of
Loading ->
"Loading"
Loaded ->
"Ready!"
NotLoaded ->
"Not loaded ..."
viewProduct : Product -> Html Msg
viewProduct p =
div []
[ text p.name
, text <| Maybe.withDefault "" p.kind
, text <| Maybe.withDefault "" p.description
, text <| String.fromFloat p.price
, a [ href ("/product/" ++ String.fromInt p.id) ] [ text "View Product" ]
]
view : Model -> Html Msg
view model =
case model.pageStatus of
Loading ->
div [] [ text <| viewStatus Loading ]
_ ->
div []
[ ul [] (List.map viewProduct model.products)
]
|