Continuing the real code – Let’s talk about update

We are working on building a real code after series of theory blogs. We are building a very simple application which allows a user to enter a name (any string) in the input box and when the user clicks the ‘Say My Name’ button it will display the name in ‘Your name is:’ label.

image

In the last blog, we looked the model component. In this blog we will look at the update component.

Think of update component as a controller in a normal MVC pattern. This part of the code listens for event changes and update the model accordingly. Once the model updated the view will be rendered again to show the event’s reaction.

Like I said previously, update component reacts to the events. Like model, update also has two components

  1. Define all the events that we are interested in listening
  2. Write code to perform tasks when an event happens

Based on the end state of the application, what are all the possible events that can occur in the application. The obvious first event will be some one clicking the button ‘Say My Name” and let’s name the event  ‘SayMyName’.  The second one will be, when ever a user enters something in the input box, data change event for the input box will be triggered. Let’s name the event as ‘InputChange’ event. That is about it.

Next question, how do we go about defining these events? In Elm you define these events with type like the following. We identified the two events and we just create a type with the two events.

type Msg = SayMyName | InputChange String

You might have question how do you define this named event and where do we define them? We will look at them when we discuss the View component in detail. For now, when someone clicks the “Say My Name” button, some how the ‘SayMyName’ message will be triggered in update section.

InputChange event definition though is little different. When someone click the button, all the framework does it to trigger an event. On the otherhand, when someone changes a value in the input field, a change event get triggered with the changed value. That is why, InputChange event defined with one String parameter.

Now that we defined the events, let’s look at what are we going to do when these events occur?

update: Msg –> Model –> Model

because Elm is static type, it is good to define the update function first.Based on the signature, update function takes the message (Msg) as first parameter, which also takes Model (current state of the application) as second parameter and at the end of the update function, it returns modified state of the application model (Model).

In the last blog we looked at the Model. In that, we identified the two required fields. One to display the name (name) and another one to hold the input data in the input field(inputdata). With that knowledge, when a user clicks the ‘Say My Name’ button, we need to do the following

  • Copy inputdata to name field
  • Reset the inputdata field to be empty (“”)

How do we do it in functional Elm? We need to take the incoming model and modify name and inputdata. The way you modify records in Elm as follows

{model | name = model.inputdata, inputdata = “”}

following the code model above, when there is a change to the input field, we need take the new value and put it in the inputdata field.

{ model | inputdata = val}

where the val is incoming value on data change. It will make sense in a bit when we look at the whole update function.

update msg model =

    case msg of

         SayMyName –>

               {model | name = model.inputdata, inputdata = “”}

         InputChange  val –>

                {model | inputdata = val }

Update function take two parameters, first is the event that triggers the update function and also the current state of the data (as model)

In Elm, we check what event was triggered by doing something similar to switch statements in other languages. If you look at the code, there are no return statements. In functional programming there are no explicit return statements instead the last statement is treated as return statement. In our update function definition, update function is supposed to return a model. If you look at the each of the case statement, both has just one line statement and both return new instance of the model with new data.

Next we will talk about view

Advertisements

First taste at real code – Let’s talk about Model

Now that we know what makes up Elm and also have your development environment setup, let’s start doing some coding and learn along the way.

For our first exercise we are going to build a very simple application like the following

image

This application will say what ever we type in the input box. On start there is no data so it is not showing anything. If I were to type my name ‘Unni’

image

and hit the ‘Say My Name’ button, it will be something like the following

image

If you notice, right after you click the ‘Say My Name’ button, the name appeared in the first line but the input field cleared.

Let’s get started.  When we build any Elm application, you need define the Model, Update and View. One best place to start is Model(or Data).

Before we go into our example code, I want to talk about model quick. Model is nothing but your application’s data structure if you will.In Elm Model has two parts,

  • Declaration of the Model
  • The startup/initialized data of the model

If the model is very simple like single data type in it, we could skip the model declaration altogether but it is best practice to always define the Model. You can define the model with ‘type’ definition. But it is always recommended to use ‘type alias’ to define the model, which will make the code much more readable. We will get to that later, for now let us assume, if you are going to define a model, always use ‘type alias’.

Now that is out of the way, let us talk about what should be our model based on the application we are building. By looking at the screen, you can see we need two data fields.

  1. A field is hold the value of the name till someone presses the ‘Say My Name’ button, let’s call that as ‘inputdata’
  2. On clicking the ‘Say My Name’ button, we need to display the name from the input field (inputdata) also at the same time we need to clear the inputdata. So we need another variable to hold display name. Let’s call that ‘name’

Now that we know we need two variables, what type are they? In this simple case both are strings. So let’s create the model data structure first

type alias Model =
     { name : String
     , inputdata : String
     }

If you remember the anotomy of Elm application blog, I mentioned, the view take a model to display  the view. So we need to pass start up date to view. Now that we know the model, let’s create the startup data.

initData : Model
initData =
     { name = “”
     , inputdata = “”
     }

Elm is static typed language so any thing you define, you need to declare its definition. Along the same line, when we define a variable, we need to define what type it is. So the first line

initData : Model

declared the initData is of type Model. Now just imagine, if you did not define the type alias it will look something like this

initData : { name : String, inputData : String }

Obviously using type alias make the code more readable. Next four lines instantiate/assign the initial value of the initData. Both the name to display and input data are empty strings.

Hope you are with me so far. I want to take a moment to correct few things I mentioned earlier in this blog. Elm is a functional programming language, that means there is no mutation. Everything is immutable. In the above code I said name and inputdata as variable. They are not really variables, they are constants in a way. If you were to change the value of either of the fields, Elm runtime will create a new instance of those fields.

Following the same model, the initData is a immutable initial startup data.  If everything is mutable, how do we hold state of an application? Hold the thought we will come back and address that later.

We will look at update component next.

Setting up Elm development environment

Now that we know some of the core fundamentals and things that make up Elm, let’s start learning by coding. For that, we need to setup the development environment first. It is simple and easy.

I was going to write step by step instructions on how to setup Elm for Atom editor but found this great Git repo. This has all the information needed to setup. Few of things you need to know as you go through them

  • Where ever, it say ‘which’ replace with ‘where’ for Windows
  • If you are using Atom if for some reason something not working, restart Atom
  • linter-elm-make required elm-make.exe, if you are in Windows, make sure when you paste the location of the elm-make, put the whole path and the file name in double quotes like the following

“C:\Program Files (x86)\Elm Platform\0.18\bin\elm-make.exe”

  • When you start a new Elm file, the Elm language may not work, for that make sure you install elm-package. Atom will complain about missing json file. Execute the following in the command prompt

elm-package install

If you face any problem following the git repo, let me know I will try to help

Let’s start with Hello World

Now that we know how all things work together, let’s try our Hello World program in couple of ways.

The first and very simple way to impress people

import Html exposing (text)
main =
   text “Hello World!”

When you write front end application using Elm, you write everything in Elm including HTML. Will talk about it later. For now when you are in Elm you will everything in Elm except CSS.  Let’s look at the code above

import Html exposing (text)

We are importing the Html function sets and we are only exposing text function for this code to work.

main =
   text “Hello World!”

All Elm program starts with “main”, this is the entry for browser to know where to start. The main program executes text function which takes just one string parameter and create the DOM element for browser to render. This is the simple and easy to way to do it. But if you were following along you will notice, there is no model, view or update of any kind. Well that is because it is simple hello world program.

Anatomy of Elm

When I started learning Angular once I understood the angular life cycle, learning Angular was easy. So I would like to do the same here for Elm also. Elm’s anatomy is simple. In my previous blog, I mentioned what are all the components constitute elm application.

Elm application has three components, model, view and update along with the main entry point. Now let’s look at how the whole thing work.

All elm application starts with entry point main. Elm comes with great bootstrap for us get started call beginnerProgram, which hides all the wiring to connect all the parts. So to get started our main entry point will be something like the following

main =

     beginnerProgram (model = data, view = view, update = messageHandlers}

Here we call the main entry point with the three components, model, view and update.

The flow of control

clip_image001

  1. On program entry, Elm reads the model data to build the view

2. View generates HTML to render with the data from the model

3. User interacts with view on each user interaction, message gets generated.

4. Messages passed to update function. Update look at the incoming messages and create new instance of the model. (It is functional program, model is immutable)

5. The new model will trigger the creation of new view and the loop repeats.

That is it.

Elm – Basic Architecture

Before you go head first into building, it is good understand the basic architecture of Elm. Most of the application follows one of the MV* pattern. Elm also follows the pattern in a different way. Elm has three distinct parts in the application

Model: As the name suggests the state of the application. You data model. Model defines and holds the current state of the application.

View: This holds the visual representation of the application, HTML, Think of this as HTML template.

Update:These are the events which triggers change in model state which triggers change in view.

When you look at Elm application, you potentially will have view, model and updates all in single Elm file. During deployment, elm will compile this file and spit out, HTML and Javascript.

With the above architecture, one would always need to have entry point to the application and that is represented by ‘main’. We will see more details how they all fit together tomorrow.

Elm – Gradual Learning

I found this video of Evan Czaplicki’s. For anyone interested in learning Elm, this is a good one to listen to. It is every entertaining and educational at the same time. There are lot of stuff in it but the one thing that caught my eye was ‘Gradual Learning’. Learning to do work in functional language is very difficult for normal programmers. Functional programming is considered theory and it has lot of constraints. The main one sticks out quickly is immutability. For people coming from C# or Java, it is a no go. It is one of the main reason there is not much adoption of functional programming. There are pockets of companies and people building enterprise grade application in functional programming but main stream always found it difficult to adopt.

Coming back to the point which caught my attention ‘Gradual Learning’. If you can get developers going quicker and then build on it over time instead of two month dedicated training will be a big win. For me, Elm provides that and I have experienced it. It is very easy to get started without knowing in and out of FP. You can build simple applications in clean Elm way in five to ten minutes. Compare to when Angular was released, this is steady learning and improving instead of wave of easy to do and then step back and spend time experimenting things before you can hit the next level.

Elm provides lot of boiler plates code for you to get started, over the period you can start to peel the layers and learn under the covers, this provides the satisfaction of progression and learning. You will see that first hand as you go through the tutorials.