Reputation: 2550
I'm currently building a small component of a web app in Elm. The elm component is compiled to a JavaScript file, loaded and then mounted on a DOM node. It should then read a config object from window.config
. (This is not something I can change.)
How can I e.g. read a string from window.config.title
to use in my Elm component? I've looked at ports, but it seems to require me to modify the generated JavaScript or wrap something around it. Is that the only option? If so, how would I simply read the value of a variable?
Upvotes: 5
Views: 1168
Reputation: 36375
Edit: Updated to Elm 0.19
If your configuration does not change over the lifetime of your app, you will probably be best served by using Browser.element or Platform.worker.
This allows for your main
function to accept a single value from Javascript during initialization. That single value can be a simple javascript object or it can even contain nested properties. The important thing is defining its shape inside Elm.
Let's say your javascript configuration looks like this:
<script>
window.options = {
foo: 123,
nested: { bar: "abc" }
};
</script>
In order to be able to pass that into your Elm file, you can define a matching shape like this:
type alias Flags =
{ foo : Int
, nested : { bar : String }
}
Now you can use Browser.element
or Platform.worker
in your Elm file like this, defining an init
function that takes Flags
as an argument:
import Html exposing (..)
import Browser
import String
main =
Browser.element
{ init = init
, view = view
, update = update
, subscriptions = subscriptions
}
init : Flags -> (Model, Cmd Msg)
init flags =
( { introText = String.concat
[ "foo is "
, String.fromInt flags.foo
, " and nested.bar is "
, flags.nested.bar
]
},
Cmd.none
)
The last piece of the puzzle is to pass your Javascript configuration option to Elm during initialization. Your html and javascript should look something like this (the relevant portion is in passing window.options
as the flags
parameter of init()
):
<body>
<div id="myContainer"></div>
<script src="Main.js"></script>
<script>
var app = Elm.Main.init( {
node: document.getElementById("myContainer"),
flags: window.options
} );
</script>
</body>
Here is a working example on ellie-app.
Upvotes: 12