On Sunday, April 26, 2015 at 3:05:29 AM UTC+10, Jeremy Vuillermet wrote:
> I'm trying to have a common flow for validating inputs.
>
> For example how and where to validate that a todo in the :add-todo event is
> valid.
>
> At first, I thought that it's the component dispatching the event which is
> responsible for validating the input. Obviously, at some point, I wanted to
> validate a todo in an other component.
>
> I had to create a valid-todo? function that any component could use. That's
> fine but then of course, I forgot to validate one and had a bug in my app
> because I was dispatching and storing an invalid todo.
>
> So I thought it make sense to validate the input in the handler. I can make a
> middleware that check if the todo is valid. Now I'm sure that nobody can
> store an invalid todo. Since all the model functions (subs, handlers and
> validators) are collocated, it allow me to easily refactor the schema without
> forgetting anything.
>
> At this point, I have two kind of invalid input. The exceptionally invalid
> input which is only possible if my app has bug and the user invalid input
> that should trigger some feedback.
> For the first one, I simply have some assert on the handler so I don't miss
> that kind of errors. It's not nice in prod but that's in progress
> https://github.com/Day8/re-frame/issues/54
>
> For the invalid user input, I'm experimenting with this flow :
> Components that could trigger some invalid input get an id into the error map
> of the global state.
> (error (subscribe [:error :todo-form])
>
> When I dispatch the :add-todo, I add the component id to the params vector
> (dispatch [:add-todo todo-data :todo-form])
>
> Then, in the handler or in a middleware if that make sense, I can :
> (if (valid-todo? todo)
> (update-in db [:todos] conj todo)
> (update-in db [:error error-id] "Todo cannot be empty"))
>
> I then just render my component based on the @error subscription
>
> So how do you guys do it ?
In the past, I've done validation via "enrich" middleware.
My preference is to rerun ALL validation code after ANY changes (after any
handler is run). The validation functions add db flags to indicate error (or
remove flags if no error state).
So the enrich validation middleware is put on every handler (or set of related
handlers).
The view components will then react by rendering any error flags they see. If,
for example, duplicate Xs were a problem, your validation code would detect
them and put a list of these duplicates into the db. View code would then see a
non-nil list of duplicates and spray explanation to the user about the problem,
perhaps mentioning the duplicates by name.
I resist creating error strings in the db -- just flags or useful data. The
view is responsible for building nice strings of explanation.
This approach obviously has pros and cons:
- it is wonderfully simple and easy to get right. So easy to test, etc.
Because you rerun validation for all changes, you never need to
worry about forgetting to add validation as the app evolves.
- if your validation is computationally expensive (takes longer than 50ms)
then you probably can't do it ALWAYS. You'll have to then use more
focused validation.
Having said all of that, in the future I might not be using enrich. Instead,
perhaps I'll be using this (or variations of it):
https://gist.github.com/mike-thompson-day8/76812d5452747bc79aac
--
Mike
--
Note that posts from new members are moderated - please be patient with your
first post.
---
You received this message because you are subscribed to the Google Groups
"ClojureScript" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/clojurescript.