Skip to content

Instantly share code, notes, and snippets.

@ericgj
Last active January 9, 2017 20:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ericgj/6b02f31691b579fda0bc2035a89c41c6 to your computer and use it in GitHub Desktop.
Save ericgj/6b02f31691b579fda0bc2035a89c41c6 to your computer and use it in GitHub Desktop.
messy page update chains
-- update triggered by browser URL change
updatePage : Pages.Page -> Model -> (Model, Cmd Msg)
updatePage page model =
let
(valueTypesStatus, valueTypesTask) =
if isLoadedValueTypes model then
( model.valueTypes
, Task.succeed model.valueTypes
)
else
( RemoteData.Loading
, ValueTypes.Server.lists -- task to load value types
)
(associatesStatus, associatesTask) =
if isLoadedAssociates model then
( model.associates
, Task.succeed model.associates
)
else
( RemoteData.Loading
, Associate.Server.listActive -- task to load list of active associates
)
progreqEditTask id =
Task.map3 (,,)
Time.Extra.currentDate
associatesTask
(Progreq.Server.fetch id) -- task to load Progreq model for editing
-- ...
in
case page of
{-- set RemoteData status on dependencies, and batch tasks into a Cmd
NOTE that what can be batched is batched, but what needs to be combined
together in the update is sequenced in progreqEditTask -- see main update below
--}
Pages.ProgreqEdit id ->
( { model |
pageProgreqEdit = RemoteData.Loading
, associates = associatesStatus
, valueTypes = valueTypesStatus
}
, Cmd.batch
[ progreqEditTask id |> Task.perform FetchedProgreqDeps
, valueTypesTask |> Task.perform FetchedValueTypes
]
)
-- ...
type Msg
= FetchedValueTypes (WebData ValueTypes)
| FetchedProgreqDeps
( Date
, WebData (List (Associate.ID, Associate))
, WebData Progreq.Edit.Model
)
-- ...
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
case msg of
FetchedValueTypes vtypesR ->
( { model | valueTypes = vtypesR }, Cmd.none )
FetchedProgreqDeps (date, assocsR, editpageR) ->
let
upd r =
( { model |
currentDate = date
, associates = assocsR
, pageProgreqEdit = r
}
, Cmd.none
)
-- here is the source of the mess: injecting the associates into the edit page state
-- (ultimately in order to initialize several autocomplete models)
editPageSuccess assocs editpage =
Progreq.Edit.setFormAssociates assocs editpage |> RemoteData.succeed
editPageFailure e =
RemoteData.Failure e
editPageDefault =
editpageR
in
{-- only tag the editPage model with Success if the dependencies are a Success,
and if not either leave it in the current state (editPageDefault) or mark it
as a Failure if any of the deps are Failures.
--}
RemoteData.succeed editPageSuccess
|> RemoteData.andMap assocsR
|> RemoteData.andMap editpageR
|> RemoteData.Extra.withNoSuccess editPageDefault editPageDefault editPageFailure
|> upd
viewPage : Model -> Html Msg
viewPage model =
case model.page of
-- ...
Pages.ProgreqEdit id ->
let
page valueTypes assocs pageData =
let static = Progreq.Edit.static model.currentDate valueTypes assocs
in
Progreq.Edit.view static pageData
|> Html.map (UpdateProgreqEdit static >> UpdatePage)
in
{-- Note the duplication of logic from the update, except now taking into account the status of the valueTypes
which were loaded async, but weren't needed to determine the state of the page model in the update
I would much prefer to only do this here and not in the update.
--}
RemoteData.succeed page
|> RemoteData.andMap model.valueTypes
|> RemoteData.andMap model.associates
|> RemoteData.andMap model.pageProgreqEdit
|> RemoteData.Extra.withNoSuccess
viewLoading viewLoading viewError
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment