ELM : Update field in a list

01 May 2018

Part 2 is now published : ELM : message passing between modules

when we work on a project which has a list or a grid, in most cases we come to a situtation where we need to update one of the field in a list of Items. In this blog we will see how we can update the field in a list.

This approch might not be appropriate for the use case with lot of list Items since we have to iterated though each item on every update. In that case please consider using a different data structure.

type alias Item =
  { description : String
  , id : Int

type alias Model =
  { items : List Item }

In view

view : Model -> Html Msg
view model =
  div [ class "panel" ]
    [ p [ class "panel-heading" ] [ text "Items" ]
    , div []
      (if (List.length model.items) > 0 then
        (List.map viewItem model.items)
        [ text "No Items to show" ]

And to render each Item we have a seperate method viewItem

viewItem : Item -> Html Msg
viewItem item =
  div [ class "panel-block" ]
    [ div [ class "columns" ]
      [ div [ class "column" ]
        [ input [ type_ "text", value item.description, onInput (UpdateDescription item.id) ] []

Now if when user edits an item, we should make sure we are updating the correct Item in the store. For this the UpdateDescription message should accept id of the item and the input value.

Since our data structure uses list, we don’t have index to update the item in list. Instead we have to map through each item and match the id and if id matches we will update the field.

update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
  case msg of
    UpdateDescription id description ->
        updateDescription item =
          if (item.id == id) then
            { item | description = description }

        items =
          List.map updateDescription model.items
        ( { model | items = items }, Cmd.none )

As of now this is pretty simple and no confusion, But gets complicated when we decide to move the ItemView to a seperate module. We see that in the next blog post.

if you have any feedback, please drop a comment below.

If you particularly enjoy my work, I appreciate donations via PayPal.
comments powered by Disqus