Inside my application I have a list of addresses, a user can select a single address, edit a field and click save.
I’m struggling with the best way to model the ‘selected’ address element of this process, currently I have:
type Address = Address (Dict Int AddressFields)
What’s the correct way to model that an address is being edited? So far I’ve come up with the following, but it’s pretty ugly.
type Address = Address (Dict Int AddressFields) (Maybe (Int, AddressFields)
Or another idea:
type Address
= Address
{ previous : Dict Int AddressData
, current : Maybe AddressData
}
But again, how do I store which field I want to update once a user clicks save? Or put another way, once a user clicks save I don’t want any address to be selected, I want the address that was updated to go back into the list and nothing be selected.
I also thought about adding an selected attribute to the record but this could introduce impossible states (eg two elements selected)
type Model =
{ addresses : Dict Int AdressField
, addressForm : Maybe (Int,AddressFieldForm)
, ...
}
And then adding and editing should be handled by the same function, only initiation would be handled differently: Adding would create an empty AddressFieldForm and editing would insert the necessary data.
I’m not quite sure though why you are using an opaque type. Maybe I’m missing something.
type Model =
{ addresses : Dict Int AdressField
, addressForm : Maybe Int
, ...
}
That way you don’t duplicate the AddressField.
Then call Dict.get id model.addresses in the view, and case on it:
view model =
case `Dict.get id model.addresses` of
Nothing -> ... -- render view when not editing anything.
Just addressField -> ... -- render view editing the address.
Which isn’t any more complex, since the addressField is inside a Maybe anyway, when it is duplicated.
Yeah, but once you edit the Field you need to start storing the Field form somewhere. You can’t store it in the dict, as the user might decide to scrap it.