This module allows to invoke JavaScript functions using the Elm's Task abstraction, which is convenient for chaining multiple API calls without introducing the complexity in the model of an Elm application.
Before TypePort can be used in Elm, it must be set up on JavaScript side. Refer to the README for comprehensive instructions.
Special version of the call that reduces amount of boilerplate code required when calling JavaScript functions
that don't take any parameters. It is eqivalent of passing Json.Encoder.null into the call.
type Msg = GotWidgetsCount (Result String Int)
TaskPort.callNoArgs "getWidgetsCount" Json.Decode.int Json.Decode.string
|> Task.attempt GotWidgetsCountA structured error describing exactly how the interop call failed. You can use this to determine the best way to react to and recover from the problem.
CallError prefix is for errors explicitly sent from the JavaScript side. The error information will be specific to the interop use case, and it should be reconsituted from a JSON payload.
InteropError prefix is for the failures of the interop mechanism itself.
Generic type representing all possibilities that could be returned from an interop call.
JavaScript is very lenient regarding its errors. Any value could be thrown, and, if the JS code
is asynchronous, the Promise can reject with any value. TaskPort always attempts to decode erroneous
results returned from iterop calls using ErrorObject variant and JSErrorRecord structure, which
contains standard fields for JavaScript Error object, but if itsn't possible, it will resorts to
ErrorValue variant followed by the JSON value as-is.
In most cases you would pass values of this type to jsErrorToString to create
a useful diagnostic information, but you might also have a need to handle certain types
of errors in a particular way. To make that easier, ErrorObject variant lifts up the error
name to aid pattern-match for error types. You may do something like this:
case error of
CallError (ErrorObject "VerySpecificError" _) -> -- handle a particular subtype of Error thrown by the JS code
_ -> -- respond to the error in a generic way, e.g show a diagnostic messageStructure describing an object conforming to JavaScript standard for Error.
Unless you need to handle very specific failure condition in a particular way, you are unlikely
to use this type.
The structure contains the following fields:
name represents the type of the Error object, e.g. ReferenceErrormessage is a free-form string typically passed as a parameter to the error constructorstackLines is a platform-specific stack trace for the errorcause optional nested error object, which is first attempted to be decoded as a JSErrorRecord, but
falls back to JSError.ErrorValue if that's impossible.Subcategory of errors indicating a failure of the interop mechanism itself.
These errors are generally not receoverable, but you can use them to allow the application to fail gracefully,
or at least provide useful context for debugging, for which you can use helper function interopErrorToString.
JSON decoder that constructs a JSError value from erroneous results returned by an interop call.
You would pass it to TaskPort.call or TaskPort.callNoArgs.
In most cases instances of InteropError indicate a catastrophic failure in the
application environment and thus cannot be recovered from. This function allows
Elm application to fail gracefully by displaying an error message to the user,
that would help application developer to debug the issue.
It produces multiple lines of output, so you may want to peek at it with something like this:
import Html
errorToHtml : TaskPort.Error -> Html.Html msg
errorToHtml error =
Html.pre [] [ Html.text (TaskPort.interopErrorToString error) ]Generates a human-readable and hopefully helpful string with diagnostic information
describing a JSError. It produces multiple lines of output, so you may want to peek at it with
something like this:
import Html
errorToHtml : TaskPort.JSError -> Html.Html msg
errorToHtml error =
Html.pre [] [ Html.text (TaskPort.jsErrorToString error) ]Convenience method for creating a user-presentable string describing an error
which occured during an interop call in case use jsErrorDecoder in your interop calls.
We are exposing tests suite to help test module's implementation details.
This is an embedded tests suite allowing to test module-internal logic. No need to use this.
Creates a Task encapsulating an invocation of a particular asyncronous JavaScript function. This function will usually be wrapped into a more specific one, which will partially apply it providing the encoder and the decoders but curry the last parameter, so that it could invoked where necessary as a
args -> Taskfunction.Because interop calls can fail, produced task would likely need to be piped into a
Task.attemptor handled further usingTask.onError.Here is a simple example that creates a
Cmdinvoking a registered JavaScript function calledpingand produces a messageGotPongwith aResult, containing either anOkvariant with a string (determined by the first decoder argument), or anErr, containing aTaskPort.Errordescribing what went wrong.The
Taskabstraction allows to effectively compose chains of tasks without creating many intermediate variants in the Msg type, and designing the model to deal with partially completed call chain. The following example shows how this might be used when working with a hypothetical 'chatty' JavaScript API, requiring to callgetWidgetsCountfunction to obtain a number of widgets, and then callgetWidgetNamewith each widget's index to obtain its name.The resulting task has type
Task (TaskPort.Error String) (List String), which could be attempted as a single command, which, if successful, provides a handyList Stringwith all widget names.