This code is problematic:
-- What is this type? Is this even sensible?
deriveState
:: forall m
. Monad m
=> Connected Store (F.Input DogForm FormState m)
-> F.State DogForm FormState m
deriveState { context, input } =
{ connection: context.connection
-- wat
--, dirty: input.dirty
--, validators: input.validators
}
There are a couple things going on here.
First, keep in mind that Formless is not a usual component and it manages a lot of state on your behalf. If you find yourself constructing the full Formless state then it’s a sign something is wrong. Instead, you generally let Formless manage its own state and you just add extra fields to it and modify those fields you added.
Second, your deriveState
function is trying to use the Formless.Input
type to construct a full Formless state, but the state contains many fields that the input type does not. For example, there is no { dirty :: Boolean }
field on the Formless.Input
type.
Third, your form component’s receiver will only receive the input that you specify in your types and that is sent directly from the parent component or store. It doesn’t receive the full Formless.Input
type. In your deriveState
function you are using the type (Connected Store (Formless.Input form state input))
, but your form component will not actually receive that as its input. Instead, it will receive only (Connected Store input)
.
Arguably this should change in Formless, because you already do provide a function input -> Formless.Input form state input
that could be used:
src/Formless/Component.purs#L118
…and this mkInput
function is used when constructing the initial state:
src/Formless/Component.purs#L122
…but it isn’t used when receiving:
src/Formless/Component.purs#L128
…even though we can and probably should use it to produce a new Formless.Input
type. Regardless, even if we did do that, it wouldn’t do anything to help the situation here.
With all of this in mind, I would recommend not writing a deriveState
function that creates a brand-new state. Instead, you want to modify the existing state. Namely, you could write something like:
deriveState
:: forall m
. Monad m
=> Connected Context { isFoo :: Boolean }
-> (F.State DogForm FormState m -> F.State DogForm FormState m)
deriveState { context, input } = _
{ connection = context.connection
, isFoo = input.isFoo
}
and use it in your receiver:
FormReceive connectedInput ->
H.modify_ $ deriveState connectedInput
You can use your connected input to create your initial Formless.Input
, of course:
mkInput { context, input } =
{ connection: context.connection
, isFoo: input.isFoo
, initialInputs: ...
, validators: ...
}
Here’s a modified version of your code, with some input from the parent and some input from the store:
https://try.purescript.org/?gist=2efb8bd56e13f19c12e1858b5f66ce69