I think I would do something like this (untested):
type alias Things =
{ thing1 : Thing
, thing2 : Thing
, thing3 : Thing
}
type alias Responses =
{ thing1 : Maybe Thing -- or perhaps 'RemoteData Thing'
, thing2 : Maybe Thing
, thing3 : Maybe Thing
}
type Model
= Loading Responses
| Loaded Things
| Error String
type Msg
= GotThing1 (Result String Thing)
| GotThing2 (Result String Thing)
| GotThing3 (Result String Thing)
init : () -> ( Model, Cmd Msg )
init () =
( Loading
{ thing1 = Nothing
, thing2 = Nothing
, thing3 = Nothing
}
, Cmd.batch
[ getThing1
, getThing2
, getThing3
]
)
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case model of
Error message ->
( model, Cmd.none )
Loaded things ->
( model, Cmd.none )
Loading responses ->
case msg of
GotThing1 (Err message) ->
( Error message, Cmd.none )
GotThing1 (Ok thing1) ->
checkIfLoaded { responses | thing1 = Just thing1 }
GotThing2 (Err message) ->
( Error message, Cmd.none )
GotThing2 (Ok thing2) ->
checkIfLoaded { responses | thing2 = Just thing2 }
GotThing3 (Err message) ->
( Error message, Cmd.none )
GotThing3 (Ok thing3) ->
checkIfLoaded { responses | thing3 = Just thing3 }
checkIfLoaded : Responses -> ( Model, Cmd Msg )
checkIfLoaded results =
case Maybe.map3 Things results.thing1 results.thing2 results.thing3 of
Just things ->
( Loaded things, Cmd.none )
Nothing ->
( Loading results, Cmd.none )
This avoids the counter and the string keys, and has the advantage of extending nicely to the case where thing1
, thing2
and thing3
are different types.