My sign-up mini app is not reactive. Things flow in one-way only - so (I maybe wrong) my app is not reactive.
I am a Python programmer and never touched F[R]P before. I read till Forms · An Introduction to Elm and wanted to add some extras.
Goals:
don’t show password feedback if password field is empty
“password again” input field should be disabled by default, and activated only if password is good (8+ characters, upper and lower case, has punctuation and numbers).
submit button becomes active only when both passwords are same.
when I start typing password, I get accurate feedback, if I remove all number, then I get feedback that digits are missing - but if I delete the entire input - the feedback stays - violating 1st goal and the stale state makes it feel non-reactive
I type good password and manage to activate password-again field, but if I then go back to password and type just “abc” then password-again becomes disabled but content locked - this looks ugly and I want it to clear
Questions
How can I achieve the goals in an elegant manner that respects elm/FRP style?
On theoretical level what was wrong in my thinking process, how can I model the signals/messages better?
How can we prevent code written in FRP from leaving stale state and looking non-reactive?
What is the elegant way to implement goal #3?
What would be the future-proof way to implement goal #3?
Ideally feedback should be bunch of paragraphs, but if I write a function showFb : String -> List msg and then do List.map showFb feedbacks I get List (List msg) so how to flatten it to List map?
I thought I’d post this in Request and Feedback - but since my app goals are not met - I am asking under the Learn tag.
Elm isn’t FRP (Functional Reactive Programming) any more, it was prior to 0.17. In version 0.17 the architecture changed from signals and FRP to TEA (The Elm Architecture). The elm guide describes this: The Elm Architecture · An Introduction to Elm
Sorry, doesn’t really answer your questions, but I thought these might be some helpful pointers to get you started working with Elm.
You commited no sins to make your app “non-reactive” - thanks to the Elm Architecture…
But you are just not finished yet.
Issue 1:
If you delete everything in the Password field, your DelPass msg is triggered with x being an empty string in your update function. There, you are validating the now empty input string - and get all validation errors. You have to handle the case where x is an empty string.
Btw. since fdbk in your model is derived from model.pass I’d suggest to not keep track of the feedback in your model at all and move the validation to your view function.
Issue 2:
If you want to clear Password2 - you have to clear pass2 in your model. I think it is save to clear pass2 every time the value of pass changes.
To finally answer your questions
Keep going - you have not covered all your goals yet and you have to update your model in the update function according to your goals. But keep in mind that you should usually not keep derived state in your model. E.g. do not keep something like passwordsAreSame in your model
You have to be explicit on what should happen for a given message - e.g. also clear pass2 if pass changes…
There is actually no stale state in your app. It works exactly as you told it. But you didn’t tell it everything it needs to implement all features and missed some stuff.
You can “Debug” your state - in Ellie, there is a Debug tab where you can inspect the actual state of your model. If the state looks correct but your Application does not what you expected, then there is something wrong in your view function. But if your state looks wrong, e.g. you have validation errors but pass is actually empty - then you have to look at your update function and fix the issue…
4+5. You can write a function that takes both passwords and returns a boolean if both are the same. Then in your view function (not in your model) disable the button if this function returns False. Again, empty strings are a special case - you probably never want to enable the button if pass is empty
You could probably use List.concatMap - go and check the documnetation of the List package: (List - core 1.0.5)
Some general (subjective) feedback on your code:
I usually try to name things what they are and not use abbreviations, e.g. feedback instead of fdbk or passwordAgain instead of pass2. Your future self will thank you for this.
It’s a common pattern to name messages after what happened. So I would name my messages PasswordChanged and PasswordAgainChanged instead of DelPass and DelPass2. First, I thought these messages are triggered when the user deletes the password input.
I hope my feedback is helpful and leads you on the right track…
Thanks for introducing me to Ellie app, I googled Elm formatters and evals but never found it.
Actually I want to write an RxJS clone and when choosing between learning Haskell or Elm - I chose Elm because Wikipedia lists it as FRP and also because I’d get visual feedback making webapps. It is surprising to know Elm isn’t FRP anymore.
I read only the first para and got some ideas (and made some silly mistakes) I will try to solve it again - and then read the full reply - thanks for the detailed reply