JavaScript interface documentation

Is there any documentation that describes the JavaScript interface to Elm? (like the init function and the subscribe function for ports)

The “Javascript Interop” section in the Elm Guide and the “Flags” and “Ports” sub-pages are probably what you want: https://guide.elm-lang.org/interop/

1 Like

Is there anything not documented there?

Nope, that’s it!
Any particular reason you ask?

1 Like

I would love to see the use of Json.Decode.Value in a flags-related example. The docs touch on it, but we’re left to figure things out from there. Are there any examples out there?

Hi,

Welcome to Elm.

I’ve not seen any examples, but it’s just a matter of decoding the flags.

The flags get passed in to init and then you can use a custom Json decoder to decode them the same way you would if the data was received over Http etc. I think what you’re actually looking for is Json.Decode examples, once you understand decoding Json, decoding flags will be a breeze.

Also, have a look at https://package.elm-lang.org/packages/NoRedInk/elm-json-decode-pipeline/latest/ . It can help in making decoding a bit simpler.

1 Like

One thing to note when passing flags through to init, or using ports, is that primitive types pass through ok, without needing to be decoded. So if your flags only contain things like Strings, Ints, Floats, Lists etc then you don’t need to go down the decoder route.

-- JS
var flags = {hello: "world"}
Elm.Main.init({node: document.getElementById("elm"), flags: flags})

-- Elm

type alias Model =
    { hello : String
    , something : Int
    , other : Float
    }

type alias Flags =
    { hello : String }

init : Flags -> Model
init flags =
    { hello = flags.hello
    , something = 1
    , other = 1.1
    }

The only time you’ll need to reach for decoders is if you need to decode what’s coming in, into an Elm custom type, or if your flags are passing in a Json encoded string.

1 Like

But arrays aren’t supported – is that right?

I guess it depends on what’s in the array, if it’s just primitives, you’re fine.

Here’s a snippet from a game I’m going to post in the next couple of days hopefully:

-- JS

 var highscores = localDataStorage('highscores')
 var total = highscores.get("total")
 var scores = []
 for( var i = 0; i < total - 1; i++) {
   scores[i] = highscores.get(i + 1)
 }


 var app = Elm.Main.init(
     { node: document.getElementById('elm'),
       flags:
         { viewport:
            { height: window.innerHeight,
              width: window.innerWidth
            },
            highscores: scores
         }
     }
);

-- Elm

type alias Flags =
    { viewport :
        { height : Float
        , width : Float
        }
    , highscores :
        List
            { name : String
            , points : Int
            }
    }

init : Flags -> Model
init flags =
    let
        players =
            Players.init
                (Lives 3)
                (Highscores
                    { list = flags.highscores
                    , max = 10
                    }
                )
    in
    StartScreen
        (StartScreen.init
            Easy
            players
        )
        (RUI.init
            (flags
                |> .viewport
            )
            |> RUI.updateMax 1680
            |> RUI.updateMin 500
        )
        (Logic.init
            Level.init
            Easy
            players
        )

flags.highscores doesn’t need decoding.

HTH

1 Like

OK I didn’t know this :slight_smile: Very helpful – thank you!

1 Like

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.