Created
December 27, 2017 11:34
-
-
Save fpapado/4b2a1d47ffcca63e66d5f0ee8f1bb82f to your computer and use it in GitHub Desktop.
Elm nested updates
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Main exposing (..) | |
-- Using let..in, newWhatever and inline functions | |
import Dict exposing (Dict) | |
type alias Model = | |
{ something : String | |
, somethingElse : String | |
, items : Dict String Item | |
} | |
type alias Item = | |
{ name : String | |
, value : Int | |
, selected : Bool | |
} | |
initModel : Model | |
initModel = | |
{ something = "Hello" | |
, somethingElse = "World" | |
, items = | |
Dict.fromList | |
[ ( "APPLE", Item "apple" 1 False ) | |
, ( "ORANGE", Item "orange" 2 False ) | |
] | |
} | |
type Msg | |
= SelectItem String | |
update : Msg -> Model -> ( Model, Cmd Msg ) | |
update msg model = | |
case msg of | |
SelectItem itemStringId -> | |
let | |
-- inline function to select item and deselect others | |
setSelected ( id, item ) = | |
if id == itemStringId then | |
( id, { item | selected = True } ) | |
else | |
( id, { item | selected = False } ) | |
-- this is silly, but we'll take care of it later | |
-- newSomething is very common for these updates | |
newItems = | |
model.items | |
|> Dict.toList | |
|> List.map setSelected | |
|> Dict.fromList | |
in | |
{ model | items = newItems } ! [] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Main exposing (..) | |
-- Here, we have a dedicated function to keep update clean | |
import Dict exposing (Dict) | |
type alias Model = | |
{ something : String | |
, somethingElse : String | |
, items : Dict String Item | |
} | |
type alias Item = | |
{ name : String | |
, value : Int | |
, selected : Bool | |
} | |
initModel : Model | |
initModel = | |
{ something = "Hello" | |
, somethingElse = "World" | |
, items = | |
Dict.fromList | |
[ ( "APPLE", Item "apple" 1 False ) | |
, ( "ORANGE", Item "orange" 2 False ) | |
] | |
} | |
type Msg | |
= SelectItem String | |
update : Msg -> Model -> ( Model, Cmd Msg ) | |
update msg model = | |
case msg of | |
SelectItem itemStringId -> | |
let | |
newItems = | |
updateSelectedItem itemStringId model.items | |
in | |
{- Could even be: | |
{model | items = setSelectedItem itemStringId model.items} | |
and then we'd skip the let..in | |
-} | |
{ model | items = newItems } ! [] | |
updateSelectedItem : comparable -> Dict comparable Item -> Dict comparable Item | |
updateSelectedItem itemId itemsDict = | |
let | |
setSelected ( id, item ) = | |
if id == itemId then | |
( id, { item | selected = True } ) | |
else | |
( id, { item | selected = False } ) | |
in | |
itemsDict | |
|> Dict.toList | |
|> List.map setSelected | |
|> Dict.fromList | |
-- You can even think of more updateSpecificModelPart functions for more nesting |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Main exposing (..) | |
{- Here, we change the definition of model to have selected as top level | |
Nested updates in general might mean some restructuring is due. Once an update | |
grows too large, you'd want sub-update functions anyway, so this is already a | |
step in that direction. | |
-} | |
import Dict exposing (Dict) | |
type alias Model = | |
{ something : String | |
, somethingElse : String | |
, items : Dict String Item | |
, selectedItem : Maybe String | |
} | |
type alias Item = | |
{ name : String | |
, value : Int | |
} | |
initModel : Model | |
initModel = | |
{ something = "Hello" | |
, somethingElse = "World" | |
, items = | |
Dict.fromList | |
[ ( "APPLE", Item "apple" 1 ) | |
, ( "ORANGE", Item "orange" 2 ) | |
] | |
, selectedItem = Nothing | |
} | |
type Msg | |
= SelectItem String | |
update : Msg -> Model -> ( Model, Cmd Msg ) | |
update msg model = | |
case msg of | |
SelectItem itemStringId -> | |
{ model | selectedItem = Just itemStringId } ! [] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment