Helps you set up Elm's ports (on the JavaScript side)
Elm's ports allow Elm to communicate with JavaScript.
I've noticed several things about ports:
I created elm-port-helper to make the JavaScript side of ports less tedious.
import ElmPorts from 'elm-port-helper'
import Elm from './Main.elm'
const app = Elm.Main.fullscreen()
ElmPorts.attachPorts({
// These first two ports are called by Elm and preform some side effect.
// They don't return data to Elm
setTitle: title => {
window.title = title
},
storageSet: ([path, value]) => {
window.localStorage[path] = value
}
},
// This port is called by Elm then returns some data
storageGet: {
// The callback.RESULT constant tells elm-port-helper to expect some result
// from the func and give it to Elm. Since a callback port name is not
// specified, this port's name plus "Finished" will be used (storageGetFinished)
callback: ElmPorts.callback.RESULT,
func: ([path]) => (
window.localStorage.getItem(path) || ''
)
}
}, {
logging: ElmPorts.logging.DEBUG
}, app)
I'd recommend defining ports in a separate file, then importing the object of ports in each JavaScript file that initializes an Elm module.
See full examples in the examples folder.
elm-port-helper
is not published on NPM yet. However, NPM can install directly
from GitHub:
npm install sidneynemzer/elm-port-helper#v1.0.1
Replace "1.0.0" with the version that you want (See the list of versions)
attachPorts( ports, options, app )
The ports
argument should be an object where the keys are the names of ports
and the values are Port Objects.
options
is an object with the following keys:
options.listenToEmptyPorts
-- Boolean (Default: true
)options.logging
.options.warnOnIgnoredReturns
-- Boolean (Default: true
)true
will print a warning if the JavaScript function for acallback
is set to false
. This warningoptions.logging
.options.logging
-- Boolean (Default: logging.ERRORS
)logging
object below.Example:
ElmPorts.attachPorts(ports, {
listenToEmptyPorts: false,
warnOnIgnoredReturns: true,
logging: ElmPorts.logging.DEBUG
}, app)
This object defines a single JavaScript port. It should be a value in the object
passed to attachPorts
port.callback
-- Boolean or Object or one of callback
(Default: false
)false
to disable.port.func
can be set directly as the valueport.callback.type
-- One of callback
(Default: callback.ERROR
)port.callback.tag
and port.callback.name
, you can just directly setport.callback
to the type, instead of the full object.port.callback.tag
-- false
or function
(Default: arg[0]
)tag
and rest
. Theport.callback.name
-- String (Default: port's name + 'Finished'
)Finished
.port.func
-- function
port.callback.type
, an error placeholder will be added to the array.Example:
ElmPorts.attachPorts({
examplePort: {
callback: {
type: ElmPorts.callback.RESULT,
// `tag` defaults to the first arg of the array, so here we need to
// explicitly retrieve the tag from the end of the args.
tag: args => ({
tag: args[3],
rest: args.slice(0, 3)
}),
// The port used to send the result to Elm
name: 'examplePortComplete'
},
func: ([val0, val1, val2]) => {
// This isn't a very useful port
// TODO Better example?
return val0.indexOf(val1) + val2
}
},
examplePort2: message => {
// This port has no callback, so the function is defined
// directly as the value instead at port.func
alert(message)
}
}, app)
callback
This built-in object provides the possible values for a port's callback option.
When the tag is disabled, RESULT_OR_ERROR
is an array with the error and result
while ERROR
and RESULT
become a plain value (not wrapped in an array).
callback.RESULT_OR_ERROR
[tag, error, null]
. A successful result turns into[tag, '', result]
(with an empty string in place of an error).callback.ERROR
[tag, error]
. Non-errors turn into [tag, null]
. Thiscallback.RESULT
[tag, result]
. Errors are not sent to Elm.callback.NONE
port.callback
to false
.logging
This built-in object provides the possible values for
attachPorts
' logging option.
logging.NONE
logging.ERRORS
logging.RESULT
logging.DEBUG
Example:
ElmPorts.attachPorts(ports, {
logging: ElmPorts.logging.DEBUG
}, app)