-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(elm): Introduce form validation library #63
Conversation
Update: Added advanced validators with regex, form is being cleared upon successful submission. |
@@ -27,7 +28,25 @@ update msg model = | |||
{ model | user = response } ! [] | |||
|
|||
OnQuestionCreated response -> | |||
model ! [] | |||
case response of | |||
RemoteData.Success responseData -> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually I'm not sure what's the point of using RemoteData since we are ignoring all of its privileges. The main cause for using it is the fact that we can distinguish between having loaded empty or not yet having loaded data etc. Seeing how we deal with this everytime makes me cringe and rethink if we should really use it at all if that's the way we're using it. I mean, we can always say that we will implement rest of the pattern checks later, but we both know it's one of the lowest priority things.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should use RemoteData. Maybe this particular piece of code is not the best example but the abstraction layer it adds is actually nice. As a developer you don't need to worry about all the edge cases that can be returned from the server.
aion/web/elm/src/Update.elm
Outdated
|
||
validationErrors = | ||
possibleFields | ||
|> List.map (\name -> Forms.errorList model.panelData.createQuestionForm name) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For me it works as the Elixir's style of aliasing nested modules - I would put let createQuestionForm = model.panelData.createQuestionForm
to get it of this dot army.
aion/web/elm/src/Update.elm
Outdated
newCreateQuestionForm = | ||
Forms.updateFormInput oldCreateQuestionForm "question" "" | ||
|
||
evenNewerCreateQuestionForm = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Haven't checked that, but instead of these three createQuestionForm lets we could do with one using pipe chains. How about createQuestionForm -> updateFormInput -> updateFormInput
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Basically if you define bindings in let area only to use them in the next binding in the same let area, that suggests that you could actually just go ahead and use a pipechain.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Im not sure how to handle it in nice way 😑
aion/web/elm/src/Update.elm
Outdated
oldPanelData = | ||
model.panelData | ||
possibleFields = | ||
[ "question", "answers", "subject" ] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I totally wouldn't hardcode these (definitely not in Update.elm, I say we stick to only having logic here, not data). Maybe we could find a cozy place for constants like that? We could put it in appropriate Models.elm or Constants.elm file.
aion/web/elm/src/Panel/View.elm
Outdated
div [] | ||
[ p [] [ text "Enter answer below, separate all posibilities with comma:" ] | ||
, input | ||
[ placeholder "4,cztery" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Polish -> English
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the views could be split to more functions, but maybe I'll do it when #56
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mrapacz elmrefactor when
aion/web/elm/src/Panel/View.elm
Outdated
listRooms : WebData RoomsData -> List String | ||
listRooms result = | ||
case result of | ||
RemoteData.Success roomsData -> | ||
List.map (\room -> room.name) roomsData.data | ||
"" :: List.map (\room -> room.name) roomsData.data |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, the ""::
part is impressive and illegible. What does it actually do? I'm sure we can come up with a better way of solving this problem
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Validation library does not provide default values. So this is a dirty hack to have empty string at the beginning to force user to choose something. If the user would like to create a new question to the first displayed category he would need to choose something else and get back to it and then hit submit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we need better solution for a dropdown menu though.
aion/web/elm/src/Update.elm
Outdated
{ model | panelData = { oldPanelData | newQuestionContent = questionContent } } ! [] | ||
{ model | ||
| panelData = | ||
{ oldPanelData | createQuestionForm = Forms.updateFormInput oldPanelData.createQuestionForm name value } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here, you get rid of the dots using improved imports or cool variable bindings in let area just above and you're left with createQuestionForm = updateFormInput createQuestionForm name value
. Seems more legible. I also think the naming could be better here. What if we changed createQuestionForm to questionForm? The create verb confuses me a lot as I imagine it is a name of a function that actually creates a questionForm
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should leave Forms
prefix so we know where this function comes from.
aion/web/elm/src/Update.elm
Outdated
if List.isEmpty validationErrors then | ||
( model, createQuestionWithAnswers model ) | ||
else | ||
model ! [] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens if there actually are errors? (serious question, what do we want to do, react somehow - flash info message or just leave it and let user figure out why it's not working?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking about displaying Toasties but Im still waiting for #59 to be merged.
aion/web/elm/src/Update.elm
Outdated
in | ||
{ model | panelData = { oldPanelData | newAnswerCategory = answerCategoryToId } } ! [] | ||
if List.isEmpty validationErrors then | ||
( model, createQuestionWithAnswers model ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's a matter or #56 but I wouldn't pass the whole model to any function (apart from main Update etc). I believe that we should always only pass one data structure from our model. Well, what if I would then need to pass like three different structures from our model, eh?
one could ask. I believe that if we split our state well, these all three different structures should end up in one bigger structure that aggregates them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pmrukot Bring ye the whole answers into the discussion.
4da66e7
to
fcdb031
Compare
@mrapacz I've updated according to your suggestions, only not sure how to handle pipe chains. For me It would be also good to merge it and adjust later since we need to move forward. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks acceptable imho, looks really neat. Let's leave it like this for now, I may fix the small things while doing the elm refactor.
Summary
Introduces form client form validation.
Related issues
#61