Suppose I have a controlled Elmish form:
type Model =
{
Query : string
IsLoading : bool
Result : Result<QueryResults, string> option
}
type Message =
| UpdateQuery of string
| ReceivedResults of Result<QueryResults, string>
let update message model =
match message with
| UpdateQuery query ->
let nextModel =
{
model with
Query = query
IsLoading = true
}
let cmd =
Cmd.OfAsync.result (async {
let! results = Api.tryFetchQueryResults query
return ReceivedResults results
})
nextModel, cmd
| ReceivedResults results ->
{
model with
IsLoading = false
Results = Some results
}, Cmd.none
Every time model.Query changes, it sends off an async request. However, if there is already a request in progress, I would like that to be cancelled and replaced with the new one.
What is a good way to do this in Elmish?
There is nothing built in to support cancellation of the underlying
XMLHttpRequest.We can, however, build some small machinery that will support cancellation-like functionality:
First, augment your
Modelwith information about the current pending query, and yourMessagewith a link (a simpleGuidwill do) to that queryNext, provide these pieces of data in your
updatefunctionFinally, check the pending query when receiving data from the server and ignore stuff not matching the link