Reputation: 1884
I encountered an issue that there are lots of round trip between a custom type and string
. When user clicks/changes an textarea
or droplist
in HTML, the onInput
caputures a string that represents the updated value in that element.
Then the message would send this string to update
function to update the model. The update
function need to convert that string to my custom type , since it was modeled that way.
type color = green | yellow | red
type alias Model =
{ name :String
,skinColor: color}
// to present `color` in html, it needs to be converted to string
viewFruitColor c =
div [] [
case c of
green -> "green"
yellow -> "yellow"
red -> "red"
,onSelect ChangeColor
]
// some ChangeColor msg here
// in update function, which handles changing the color of fruit, it has to convert a string back to a type
update msg model =
case msg of
ChangeColor s // s -> String here
let newColor = // can we just get `s` as a color type instead of a String ??
case s of
"green"-> green
"yellow" -> yellow
"red" -> red
in
{ fruit | skinColor = newColor }
this is only for one single field in model
, what if there are mutilple fields, that would boost up a lots of reduntant codes just taking round trips between type
and string
(lots of case
clauses)
Upvotes: 2
Views: 107
Reputation: 7159
Just use functions, elm was designed to write code like this:
colorToString : color -> String
colorToString c =
case c of
green -> "green"
yellow -> "yellow"
red -> "red"
parseColor : String -> color
parseColor s =
case s of
"green"-> green
"yellow" -> yellow
"red" -> red
_ -> red -- it is a good idea to have a default, or otherwise use the Maybe type
And then your code would work for example like
viewFruitColor c =
div [] [
colorToString c
,onSelect ChangeColor
]
There is no way to bypass it. The user can send you an arbitrary string and you need to handle it. On the other hand, on the app side it is good to work with algebraic types as you do, because it defines the domain more precisely. The overall strategy is:
parseColor
color
colorToString
Upvotes: 4