1
1
module AffEx where
2
2
3
3
import Prelude
4
-
5
4
import Data.Either (either )
6
5
import Data.Maybe (Maybe (..), maybe )
7
6
import Effect.Aff (Aff , Milliseconds (..), delay , error , message , throwError )
@@ -15,19 +14,18 @@ mkAffEx :: CreateComponent {}
15
14
mkAffEx = do
16
15
-- A component for fetching and rendering a Cat entity.
17
16
catDetails <- mkCatDetails
18
-
19
17
component " AffEx" \props -> React .do
20
18
catKey /\ catChooser <- useCatKeyChooser
21
-
22
- pure $ R .div
23
- { style: R .css { display: " flex" , flexFlow: " column" }
24
- , children:
19
+ pure
20
+ $ R .div
21
+ { style: R .css { display: " flex" , flexFlow: " column" }
22
+ , children:
25
23
[ R .h2_ [ R .text " Cat chooser" ]
26
24
, R .p_
27
- [ R .text $
28
- " Select a key to fetch! If you get bored (how would you even!?) " <>
29
- " try holding your arrow keys to select really fast! The result " <>
30
- " always matches the chosen key."
25
+ [ R .text
26
+ $ " Select a key to fetch! If you get bored (how would you even!?) "
27
+ <> " try holding your arrow keys to select really fast! The result "
28
+ <> " always matches the chosen key."
31
29
]
32
30
, catChooser
33
31
, R .p_
@@ -36,60 +34,63 @@ mkAffEx = do
36
34
Just k -> element catDetails { catKey: k }
37
35
]
38
36
]
39
- }
37
+ }
40
38
where
41
- -- This hook packages up some interactive UI and the current
42
- -- selection the user has made via that UI.
43
- useCatKeyChooser :: Hook _ ((Maybe (Key Cat )) /\ JSX )
44
- useCatKeyChooser = React .do
45
- catKey /\ setCatKey <- useState Nothing
46
- let
47
- catChoice key =
48
- R .label_
49
- [ R .input
50
- { type: " radio"
51
- , name: " cat-key"
52
- , checked: Just key == catKey
53
- , onChange: handler_ do
54
- setCatKey \_ -> Just key
55
- }
56
- , R .text $ showCatKey key
57
- ]
58
-
59
- showCatKey :: Key Cat -> String
60
- showCatKey (Key key) = " Cat " <> key
39
+ -- This hook packages up some interactive UI and the current
40
+ -- selection the user has made via that UI.
41
+ useCatKeyChooser :: Hook _ ((Maybe (Key Cat )) /\ JSX )
42
+ useCatKeyChooser = React .do
43
+ catKey /\ setCatKey <- useState Nothing
44
+ let
45
+ catChoice key =
46
+ R .label_
47
+ [ R .input
48
+ { type: " radio"
49
+ , name: " cat-key"
50
+ , checked: Just key == catKey
51
+ , onChange:
52
+ handler_ do
53
+ setCatKey \_ -> Just key
54
+ }
55
+ , R .text $ showCatKey key
56
+ ]
61
57
62
- pure $ catKey /\ fragment
63
- [ catChoice $ Key " abc"
64
- , catChoice $ Key " def"
65
- , catChoice $ Key " xyz"
66
- ]
67
-
68
- -- Hooks can't be used conditionally but components can!
69
- -- Not needing to deal with a `Maybe` key simplifies this
70
- -- compoennt a bit.
71
- mkCatDetails :: CreateComponent { catKey :: Key Cat }
72
- mkCatDetails = do
73
- component " CatDetails" \{ catKey } -> React .do
74
- cat <- useAff catKey $ fetch catKey
75
- pure $ R .text $
76
- maybe " Loading..." (either message showCat) cat
77
- where
78
- showCat (Cat { name }) = " A cat named " <> name
58
+ showCatKey :: Key Cat -> String
59
+ showCatKey (Key key) = " Cat " <> key
60
+ pure $ catKey
61
+ /\ fragment
62
+ [ catChoice $ Key " abc"
63
+ , catChoice $ Key " def"
64
+ , catChoice $ Key " ghi"
65
+ , catChoice $ Key " xyz"
66
+ ]
79
67
68
+ -- Hooks can't be used conditionally but components can!
69
+ -- Not needing to deal with a `Maybe` key simplifies this
70
+ -- compoennt a bit.
71
+ mkCatDetails :: CreateComponent { catKey :: Key Cat }
72
+ mkCatDetails = do
73
+ component " CatDetails" \{ catKey } -> React .do
74
+ cat <- useAff catKey $ fetch catKey
75
+ pure $ R .text
76
+ $ maybe " Loading..." (either message showCat) cat
77
+ where
78
+ showCat (Cat { name }) = " A cat named " <> name
80
79
81
80
-- Typed keys are a great way to tie entity-specific behavior
82
81
-- to an ID. We can use this phantom type to write a class
83
82
-- for generic, type-safe data fetching.
84
- newtype Key entity = Key String
83
+ newtype Key entity
84
+ = Key String
85
+
85
86
derive instance eqKey :: Eq (Key entity )
86
87
87
88
class Fetch entity where
88
89
fetch :: Key entity -> Aff entity
89
90
90
-
91
91
-- An example entity
92
- newtype Cat = Cat { name :: String }
92
+ newtype Cat
93
+ = Cat { name :: String }
93
94
94
95
instance fetchCat :: Fetch Cat where
95
96
fetch = case _ of
@@ -99,6 +100,9 @@ instance fetchCat :: Fetch Cat where
99
100
Key " def" -> do
100
101
delay $ Milliseconds 600.0
101
102
pure $ Cat { name: " Maxi" }
103
+ Key " ghi" -> do
104
+ delay $ Milliseconds 900.0
105
+ pure $ Cat { name: " Chloe" }
102
106
_ -> do
103
107
delay $ Milliseconds 900.0
104
108
throwError $ error " Cat not found (intended example behavior 😅)"
0 commit comments