From now on, we will use Ellie to write Elm code.
You can open the cheatsheet I created but I advise you to also open the official documentation: Elm documentation. There is also a French Version of the official Doc and a French version of my cheatsheet
-
Open this link: Basic counter
-
Goal 1: Add a reset button.
- Add a new message
Reset
and try to compile the code.-
type Msg = Increment | Decrement | Reset
-
- You will see that the compiler is complaining because the
update
function is not handling the new message. - Add a new case to the
update
function to handle theReset
message. - Add a new button to the
view
function to trigger theReset
message.
- Add a new message
-
Goal 2: Add 2 buttons, one to multiply by 2 and one to multiply by 3.
- Add a new message
MultiplyBy Int
and try to compile the code. - You will see that the compiler is complaining because the
update
function is not handling the new message. - Add a new case to the
update
function to handle theMultiplyBy
message.- Hint:
MultiplyBy nb -> ...
will match the message and bind thenb
variable to the value passed to the message.
- Hint:
- Add 2 new buttons to the
view
function to trigger theMultiplyBy
message.
- Add a new message
-
Open this link: Login form
-
Goal 1: Add a password length check.
- Update the
viewValidation
function to add a check ensuring that the password is longer than 8 characters. - You can use the String.length function to get the length of a string.
-
if String.length "hello" == 42 then "The answer to life, the universe, and everything" else "Something else"
- Update the
-
Goal 2: Add checks for character variety in password.
- Add checks to ensure the password contains uppercase, lowercase, and numeric characters.
- You should check String package for useful functions
- This one will be useful: String.any in combination with Char.isUpper, Char.isLower, and Char.isDigit.
-
String.any Char.isUpper "hello" == False String.any Char.isLower "hello" == True String.any Char.isDigit "hello" == False
-
Open this link: Random quote generator
-
Goal: When fetching a new quote, fetch a cat image from The Cat API and display it next to the quote.
-
Add a new field to the
Model
to store the image url-
type alias Model = { quote : WebData Quote , catImageUrl : WebData String }
- Now try to compile the code. You will see that the compiler is complaining because the
init
function is not handling the new field:
Line 21, Column 5 Something is off with the body of the `init` definition: 21|> ( { quote = NotAsked } 22|> , getRandomQuote 23|> ) The body is a tuple of type: ( { quote : RemoteData e a }, Cmd Msg ) But the type annotation on `init` says it should be: ( Model, Cmd Msg ) Hint: Looks like the catImageUrl field is missing.
-
Inspire yourself from the
quote
field to initialize thecatImageUrl
field. -
If you want only one button to fetch the quote and the image, you can use the Cmd.batch function to combine the 2 commands into one.
Cmd.batch [ getRandomQuote , getRandomCatImage ]
-
You can use the Json.Decode.at function to extract the image url from the response:
(Decode.at [ "0", "url" ] Decode.string)
since the only field we are interested in is theurl
field of the first element of the array. -
To display the image, you can use the img function from the Html package in combination with the src attribute
img [ src "https://www.example.com/cat.jpg" ] []
-
-
Check how to play ones again outside of the sandbox with Time using subscriptions
Open this link: Go here
The original Elm code creates a simple application with a counter, where the user can increase or decrease the count. The updated version is more complex and involves handling multiple counters, each with a step size and a history of values. Additionally, the updated version allows counters to be reset and undone.
Let's break this down into a series of tasks:
The first task involves defining a new type Counter
that will represent each individual counter in the app. This includes the count, the step size, the history, and the last message.
The Model, which was previously a single Counter, is now a List of Counters. Redefine the Model to reflect this change.
Change the init
function to initialize the Model as a List with one Counter.
The Messages have been expanded to include more types of actions. Modify the Msg type to reflect these changes. The new Messages include Plus1
, Minus1
, Reset
, SetStep
, Undo
, and NewCounter
, each with an associated id
.
The update
function is now much more complex. It now needs to update specific Counters in the Model based on their id
and handle new types of Messages. It should update the Counter's count, step size, history, and last message as appropriate for each type of Message.
The view
function should be updated to render a List of Counters. Each Counter should display its count, step size, and history. The Counter should also have buttons for each action that can be performed on it: increase, decrease, reset, undo, and change step size.
Create a new function, displayLastMsg
, to handle the display of the last message for each counter based on the maybeMsg
parameter.
Finally, update the main
function to use the new init
, update
, and view
functions in the Browser.sandbox
call.
After each task, the team should take some time to discuss and understand what was done, why it was done, and how it contributes to the overall project. This will help team members to solidify their understanding of the Elm language, its architectural pattern, and the logic of the application.
Complete Code Exercise 1 - Elite Version
Elm is a delightful language for reliable webapps. Generate JavaScript with great performance and no runtime exceptions.