Search code examples
electronelm

Cannot read property 'Elm' of undefined while using Elm 0.19 in Electron


I’m experimenting Elm 0.19 with Electron building a simple Elm app (based on the Counter example) in Electron. When I run electron-forge start, I get an error that says Cannot read property 'Elm' of undefined highlighting scope[‘Elm’] part of the elm.js file.

function _Platform_export(exports) {
    scope[‘Elm’] ? _Platform_mergeExportsDebug(‘Elm’, scope[‘Elm’], exports) : scope[‘Elm’] = exports;
}

The interesting thing is that the exact same files (Main.elm, index.html) open up just fine (showing the counter as expected), if I run elm-live Main.elm --open -- --output=elm.js instead.

So it appears that this passed to elm.js in Electron is undefined, which then caused scope to be undefined.

The Chrome Dev Tool shows the scope variable passed to elm.js is undefined in the case of the Electron app. In the case of elm-live, that value was the Window object.

elm.js

(function(scope){
'use strict';

 --- omitted ----

    var author$project$Main$main = elm$browser$Browser$sandbox({ init: author$project$Main$init, update: author$project$Main$update, view: author$project$Main$view });
    _Platform_export({ 'Main': { 'init': author$project$Main$main(elm$json$Json$Decode$succeed(_Utils_Tuple0))(0) } });
})(undefined);

elm.js? [sm]

(function(scope){
'use strict';

 --- omitted ----

var author$project$Main$main = elm$browser$Browser$sandbox(
    {init: author$project$Main$init, update: author$project$Main$update, view: author$project$Main$view});
_Platform_export({'Main':{'init':author$project$Main$main(
    elm$json$Json$Decode$succeed(_Utils_Tuple0))(0)}});}(this));

Error message

Uncaught TypeError: Cannot read property 'Elm' of undefined
    at _Platform_export (elm.js:1949)
    at elm.js:4004
    at elm.js:4005
index.html:44 Uncaught ReferenceError: Elm is not defined
    at index.html:44

Index.html

<!DOCTYPE HTML>
<html>

<head>
</head>

<body>
    <div id="elm"></div>
</body>
<script src="./elm.js"></script>
<script>
    var app = Elm.Main.init({
        node: document.getElementById('elm')
    });
</script>
</html>

Main.elm

import Browser
import Html exposing (Html, button, div, text)
import Html.Events exposing (onClick)


main =
  Browser.sandbox { init = init, update = update, view = view }


-- MODEL

type alias Model = Int

init : Model
init =
  0


-- UPDATE

type Msg = Increment | Decrement

update : Msg -> Model -> Model
update msg model =
  case msg of
    Increment ->
      model + 1

    Decrement ->
      model - 1


-- VIEW

view : Model -> Html Msg
view model =
  div []
    [ button [ onClick Decrement ] [ text "-" ]
    , div [] [ text (String.fromInt model) ]
    , button [ onClick Increment ] [ text "+" ]
    ]

Solution

  • In the Elm #electron channel on Slack, I saw a discussion about this issue and here is a recap for anyone interested.

    1. The issue is that 'this' is not defined in the electron renderer
    2. This causes scope within Elm runtime to be undefined.
    3. Possible work-around is