Skip to content

Commit f794a5b

Browse files
Fix concurrency issues in effectful form combinators (#29)
1 parent 0c4c133 commit f794a5b

File tree

1 file changed

+19
-14
lines changed

1 file changed

+19
-14
lines changed

src/Lumi/Components/Form.purs

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -786,17 +786,20 @@ fetch_ loading getData = fetch loading "" (const getData)
786786
-- | A dummy form that, whenever the specified key changes, performs an
787787
-- | asynchronous effect. It displays the specified JSX while the effect is not
788788
-- | complete, sets the form data to the result of the effect and returns it.
789-
asyncEffect :: forall props a. String -> JSX -> Aff a -> FormBuilder props a a
789+
asyncEffect :: forall props a. String -> JSX -> Aff (a -> a) -> FormBuilder props a a
790790
asyncEffect key loader aff =
791-
withKey key $ formBuilder_ \_ _ onChange ->
792-
keyed key $ asyncWithLoader loader do
793-
newValue <- aff
794-
liftEffect $ onChange newValue
795-
mempty
791+
withKey key $ formBuilder \_ value ->
792+
{ edit: \onChange ->
793+
keyed key $ asyncWithLoader loader do
794+
f <- aff
795+
liftEffect $ onChange f
796+
mempty
797+
, validate: Just value
798+
}
796799

797800
-- | A dummy form that, whenever the specified key changes, performs an
798801
-- | effect. It sets the form data to the result of the effect and returns it.
799-
effect :: forall props a. String -> Effect a -> FormBuilder props a a
802+
effect :: forall props a. String -> Effect (a -> a) -> FormBuilder props a a
800803
effect key = asyncEffect key mempty <<< liftEffect
801804

802805
-- | Sequential `SeqFormBuilder` used for asynchronously initializing some
@@ -823,16 +826,18 @@ initializer
823826
:: forall props value
824827
. Nub (initialized :: Boolean | value) (initialized :: Boolean | value)
825828
=> JSX
826-
-> (props -> {| value } -> Aff {| value })
829+
-> (props -> {| value } -> Aff ({ initialized :: Boolean | value } -> { initialized :: Boolean | value }))
827830
-> SeqFormBuilder props { initialized :: Boolean | value } Unit
828831
initializer loader aff =
829832
sequential "initializer" $ withValue \value@{ initialized } -> withProps \props ->
830-
if initialized
831-
then pure unit
832-
else
833-
invalidate $ void $ asyncEffect "" loader do
834-
newValue <- aff props (contractValue value)
835-
pure $ disjointUnion { initialized: true } newValue
833+
if initialized then
834+
pure unit
835+
else
836+
invalidate
837+
$ void
838+
$ asyncEffect "" loader
839+
$ map (_{ initialized = true } <<< _)
840+
$ aff props (contractValue value)
836841
where
837842
contractValue :: { initialized :: Boolean | value } -> {| value }
838843
contractValue = unsafeCoerce

0 commit comments

Comments
 (0)