Is there a package that implements a request/response pattern for use with pairs of ports? In such a way, that when making the request you can specify what Msg
to give on the response?
So it would work a bit like Task.attempt
:
attempt : (Result x a -> msg) -> Task x a -> Cmd msg
There when running a Task
, I supply a function telling attempt
what message to build and pass to the update
function, up-front.
The problem with ports, is that if you have a pair of ports, you must listen for the response as a subscription. For example:
port saveToLocalStorage : Value -> Cmd msg
port localStorageResult : (Value -> msg) -> Sub msg
This localStorageResult
port knows nothing about the request that it is a response to. For example, I might like to save something to local storage as part of a chain of operations, so I need to know when it has saved succesfully, and then continue with the next operation after that. The same saveToLocalStorage
operation could be used in many different chains of operations.
I tell the subscription what message to generate, but what I really want is to tell the outgoing port call what message I want it to respond with.
I have implemented this pattern, as described below, but on elm-serverless
which has additional complications, since it must also track multiple connections. Just wondering if there is already a package which implemets this pattern in a more minimal way for regular elm applications?
It does mean having to hold a context in your Model, and also putting functions in your Model, to do this.
===
I have implemented this in [Serverless - elm-serverless 4.0.0]. Since elm-serverless
has a context record called Conn
, there was already a convenient place to hold the context.
type alias Conn msg =
{ currentSeqNo : Int
, context : Dict (Int, Value -> msg)
, ...
}
When making a port call, I bump to a unique sequence number. Against the unique sequence number, I hold a Value -> msg
function. When the response comes back in the subscription, the context
is looked up in the Dict
, a message is generated from the response, and then update
is called with that message.