11module AffEx where
22
33import Prelude
4-
54import Data.Either (either )
65import Data.Maybe (Maybe (..), maybe )
76import Effect.Aff (Aff , Milliseconds (..), delay , error , message , throwError )
@@ -15,19 +14,18 @@ mkAffEx :: CreateComponent {}
1514mkAffEx = do
1615 -- A component for fetching and rendering a Cat entity.
1716 catDetails <- mkCatDetails
18-
1917 component " AffEx" \props -> React .do
2018 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:
2523 [ R .h2_ [ R .text " Cat chooser" ]
2624 , 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."
3129 ]
3230 , catChooser
3331 , R .p_
@@ -36,60 +34,63 @@ mkAffEx = do
3634 Just k -> element catDetails { catKey: k }
3735 ]
3836 ]
39- }
37+ }
4038 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+ ]
6157
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+ ]
7967
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
8079
8180-- Typed keys are a great way to tie entity-specific behavior
8281-- to an ID. We can use this phantom type to write a class
8382-- for generic, type-safe data fetching.
84- newtype Key entity = Key String
83+ newtype Key entity
84+ = Key String
85+
8586derive instance eqKey :: Eq (Key entity )
8687
8788class Fetch entity where
8889 fetch :: Key entity -> Aff entity
8990
90-
9191-- An example entity
92- newtype Cat = Cat { name :: String }
92+ newtype Cat
93+ = Cat { name :: String }
9394
9495instance fetchCat :: Fetch Cat where
9596 fetch = case _ of
@@ -99,6 +100,9 @@ instance fetchCat :: Fetch Cat where
99100 Key " def" -> do
100101 delay $ Milliseconds 600.0
101102 pure $ Cat { name: " Maxi" }
103+ Key " ghi" -> do
104+ delay $ Milliseconds 900.0
105+ pure $ Cat { name: " Chloe" }
102106 _ -> do
103107 delay $ Milliseconds 900.0
104108 throwError $ error " Cat not found (intended example behavior 😅)"
0 commit comments