halfzebra/create-elm-app

'TypeError: currentSubs[i] is not a function' when using ports in Elm 0.19

mpgirro opened this issue · 2 comments

Is this a bug report?

yes

Environment

  1. node -v: v10.10.0
  2. npm -v: 6.4.1
  3. yarn --version (if you use Yarn): -
  4. npm ls create-elm-app -g: create-elm-app@3.0.6

Then, specify:

  1. Operating system: macOS 10.14.3
  2. Browser and version (if relevant): Safari/Chrome/Firefox

Steps to Reproduce

I have created a project using create-elm-app. In this project, I am attempting to send data from Elm 0.19 to JavaScript using ports. I have a general problem when trying to do so. I provide a minimal example here to illustrate the issue (demo project below).

In Elm, I declare an outgoing port:

port modelToJs : Json.Encode.Value -> Cmd msg

which I use in the update function to produce a Cmd that sends a JSON encoded value to JavaScript.

In index.js I register the data handler that should process any data that Elm sends to JS:

app.ports.modelToJs.subscribe(function dataHandler(data) {
    console.log("got from Elm:" + data);
});

Expected Behavior

When modelToJs is called, I expect that the data handler function I register in the index.js gets called.

Actual Behavior

When modelToJs is called, the data is not sent and printed to the console. Instead, I get the following JavasScript runtime error (which Elm normally avoids by design):

error

I have checked the debugger at the relevant position. currentSubs[i] (with i == 0) is {}, i.e. the result is not a function and value cannot be applied to it.

Note: This issue only occurs when using elm-app start to run the application.

Reproducible Demo

I have also provided a full proof of concept project that reproduces the issue GitHub: https://github.com/mpgirro/elm0.19-ports-issue

Hello Maximilian!

Thanks for reaching out and making a reproducible example of your problem. 👍

I'm afraid in this particular case the problem is in dataHandler.js.

It needs to export the handler.
Otherwise, Elm will try to use undefined as a subscriber to the port.

export function dataHandler(data) {
    console.log("got from Elm:" + data);
}

I hope this helps!

Thanks a lot! This solved my problem.