Finish `SignUp` example
Closed this issue · 11 comments
@thomashoneyman I've added sign up form to test suite which is tested against Http data source:
https://github.com/paluh/purescript-polyform/blob/master/test/Polyform/Input/Http.purs#L116
I'm going to move this example to docs this weekend.
And here is relevant test:
https://github.com/paluh/purescript-polyform/blob/master/test/Polyform/Input/Http.purs#L186
Thanks @paluh! I've been working on a minimal formlets implementation for Halogen, but if Polyform is able to work well with Halogen, I'd love to contribute to the library. I'll pull it down this weekend and see how far I get. Have you tried this yet?
Unfortunately I'm testing this library on the backend currently (hence Input.Http
module ;-)). I'm afraid that in order to use it on frontend or with JSON you have to write your own "data input" like Input.Record
or use Input.Interpret
and write interpretations... This library is still in beta stage ;-)
But... I want to write simple implementation of #1 so probably I will provide some stub for Input.JSON
;-)
@thomashoneyman This signup form is also quite nice candidate to check if this is feasible with this library #4 because we have "local" passwords and inputs checks and "remote" email check ;-)
Right -- being able to mix monadic / applicative is vital. For us, flexible rendering matters a lot as well, and so the Halogen HTML base is critical.
you have to write your own "data input" like Input.Record or use Input.Interpret and write interpretations
Noted!
I can provide wrapper around Form.Validation
(like Form.Validation.Monad.ValidationM
) and you are going to get Monad
instance but at a price of loosing the accumulative nature of Applicative
(side note: I can't provide Monad
instance for existing Validation
type which wouldn't be compatible with existing Applicative
instance). Let's consider two expressions.
Here we have applicative validation in action:
passwordFormA = { password1: _, password2: _ } <$> password1Form <*> password2Form
It appends password1Form
"form" and password2Form
into single form under the hood (the idea is really taken from purescript-validation) regardless of the first step result (I mean emailForm
validation step).
This monadic version (here password1Form
and password2Form
are hypothetical ValidationM
values) behaves differently though:
passwordFormM = do
password1 <- password1Form
password2 <- password2Form
if password1 != password2
then formError "Passwords don't match"
else pure { email, password }
It won't append the second "form" from password2Form
when password1Form
validation fails, because the whole monadic block after password1 <- password1Form
can depend on the password1
value so there is no way to continue when password1Form
fails. In other words you won't get the whole "form" value (which you probably want to render) and you won't get all errors (because it would stop on the first).
This library solves this problem by providing Category
instance (expanded version ;-)):
passwordFormA >>> (Validation $ \{ password1, password2 } ->
pure $ if password1 != password2
-- I don't now here exact structure of your possible form so I'm using hypothetical heper
then Invalid (errorForm "Passwords don't match")
else Valid mempty password1
what would be great is mixing the two with https://pursuit.purescript.org/packages/purescript-parallel/3.2.0/docs/Control.Parallel#t:Parallel:
liftPar2 f a b = sequential $ lift2 f (parallel a) (parallel b)
passwordFormM = do
{ password1, password2 } <- liftPar2 { password1: _, password2: _ } password1Form password2Form
if password1 != password2
then formError "Passwords don't match"
else pure password1
@MonoidMusician This is really cool idea. I'm going to look into that and try to provide appropriate instances!
I'm still not sure if I should provide ValidationM
wrapper for Form.Validation
, but here is a type which provides parallel wrapper for our Applicative
version:
https://github.com/paluh/purescript-polyform/blob/master/src/Polyform/Form/Validation/Par.purs