🌳
Walking though the Elm woods
  • Introduction
  • Structure of the book
  • Frequently asked questions
    • How can different types share data?
    • How to break Dependency Cycles?
    • How to structure an Elm project?
    • How to turn a Msg into a Cmd Msg?
    • How to update nested Records?
    • What are comparable types?
    • Why are Booleans bad?
    • 🔜Future topics
  • Recipes
    • Writing a Single Page Application
      • Share state across pages
      • Debounced Validation
      • Reusable views
    • Making impossible states Impossible
      • Non empty lists using Zippers
      • Restrict records using Opaque Types
      • Write safer functions using Phantom Types
    • Designing Elm package APIs
      • Create upwards compatible APIs
    • 🔜Future topics
  • Frameworks and packages
    • elm/parser
    • mdgriffith/elm-ui
    • 🔜Future topics
Powered by GitBook
On this page
  • Question
  • Answer
  • Further reading

Was this helpful?

  1. Frequently asked questions

How to update nested Records?

PreviousHow to turn a Msg into a Cmd Msg?NextWhat are comparable types?

Last updated 5 years ago

Was this helpful?

Not best practice: Create an instead.

type alias Movie = 
    { title : String
    , rating : Int
    }
  
type alias Model = 
    { currentMovie : Movie
    }

rate : Int -> Model -> Model
rate newRating model =
    { model 
    | currentMovie = 
        --{ model.currentMovie | rating = newRating }
        Debug.todo "the line above does not compile"
    }
type alias Movie = 
    { title : String
    , rating : Int
    }
  
type alias Model = 
    { currentMovie : Movie
    }

rate : Int -> Model -> Model
rate newRating ({currentMovie} as model) =
    { model 
    | currentMovie = 
        {currentMovie | rating = newRating }
    }
type alias Movie = 
    { title : String
    , rating : Int
    }
  
type alias Model = 
    { currentMovie : Movie
    }

rate : Int -> Model -> Model
rate rating ({currentMovie} as model) =
    model
    |> updateMovie (addRating rating)

updateMovie : (Movie -> Movie) -> Model -> Model
updateMovie fun ({currentMovie} as model) =
    { model | currentMovie = fun currentMovie}
   
addRating : Int -> Movie -> Movie
addRating rating movie =
    { movie | rating = rating}

This is the a better solution

Question

How can I update a nested record field?

Answer

First get the nested record, then update it:

let
    currentMovie = model.currentMovie
in
{ currentMovie | rating = newRating}

For function parameters we can use the keyword as to bind fields of a record to a variable with the same name:

rate newRating ({currentMovie} as model) =
    ...

Further reading

📄Article: by Wouter In t Velt

opaque type
Updating nested records in Elm