#Elmlang – Displaying a list

Continuing our project, in the last blog we took our initial step at displaying a single best opening credit with a simple model. In this blog we will see how do we go about displaying list of opening credits.

Let’s start with model. In the previous example, what we had was just one record with title and url. Now to show a collection, we need to create list of records. Let’s see how would we define the list of records

type alias Model = List

   {  title: String

    , url: String

   }

All we did in this definition compared to previous one was to add ‘List’ in the definition. Even though this definition is all and good, there will be times where you will need to pass just a single record between functions, like displaying one record. So we need to split the definition to represent a record and list of record. With that refactoring the definition would look like this

type alias Model = List

     Record

type alias Record =

      {  title: String

        , url : String

       }

Here we defined a single record definition as record and then created a Model which is list of records.

Next we modify the initial data to hold more than one best opening credits. So I added True Detective season 2 opening credits.

initData : Model
initData =
     [ { title = “Game of Thrones”
       , url = https://www.youtube.com/embed/s7L2PVdrb_8
       }
     , { title = “True Detective Season 2”
       , url = https://www.youtube.com/embed/GJJfe1k9CeE
       }
     ]

There will be no change to update function as there are no user interactions yet.

View is going to be interesting. So far all the controls we have created are all just single controls never displayed anything that is a collection.  How do we go about doing this?

Let’s look at the view from previous blog

view : Model -> Html Msg
view model =
     div []
         [ h1 [] [ text initData.title ]
         , iframe [ width 420, height 315, src initData.url ] []

        ]

The above view function takes Model and creates the view for Elm to render. Now that we modified the Model to List, we need to modify the definition to be Record instead of Model to just display single record.

view : Record-> Html Msg
view record=
     div []
         [ h1 [] [ text record.title ]
         , iframe [ width 420, height 315, src record.url ] []

        ]

This can not be the view, because view needs to generate all the records to display, so let’s change the name of view to a different name to represent what it does, it displaying a single record

displayLine : Record -> Html Msg
displayLine record =
     div []
         [ h1 [] [ text record.title ]
         , iframe [ width 420, height 315, src record.url ] []
         ]

Now we need to modify the view to call this function for every record in the list, that is it. In Elm, there is no iteration or loop instead we will call map function.

view : Model -> Html Msg
view model =
     div []
         (List.map displayLine model)

Let’s look at the view definition closer. View definition states, it takes Model (which is list of records) and generate the HTML view for Elm to render. The view function definition has just one function call that is div. As stated in the previous blog, view function takes two arguments. First set of arguments are the function attributes and second set of arguments are list of children.  In the above definition, the second parameter is (List.map displayLine model), what does it mean?

Let’s look at the definition from left to right. There are three words in the statement. ‘List.map’, ‘displayLine’ and ‘model’.  We know the last two, ‘displayLine’ is a function which takes a record and display the records title and url. The last parameter is ‘model’, which is list of record. So it looks like we are calling List.map function, with two parameters. 

List.map’s first argument is a function which takes list as a parameter and produces list as result.

With that if you look at our call, List map call displayLine for every record in the model and generates one line display for the given record. List.map function always returns a list. Like all HTML function calls, Div function expects the second argument to be list of children and List.map returns the list of displayLine.

If you run the application, you should see a result similar to the following

image

You can find the latest  code @ https://github.com/ksunair/bestopeningcredits

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s