10

Is there a way to define a subscription port with no parameters in Elm?

Something like:

port updateTime : () -> Sub msg

With this code, I'm getting the error that "Port 'updateTime' has an invalid type"

With the code:

port updateTime : (String -> msg) -> Sub msg

It's working but I don't need to send nothing from the javascript function to Elm.

robertjlooby
  • 7,160
  • 2
  • 33
  • 45
Buda Gavril
  • 21,409
  • 40
  • 127
  • 196

1 Answers1

14

The closest you can get is probably something like this: Create the port similar to your examples but with the first parameters as (() -> msg):

port updateTime : (() -> msg) -> Sub msg

Assuming you have an UpdateTime Msg that accepts no parameters,

type Msg
    = ...
    | UpdateTime

You can then tie into the updateTime subscription like this:

subscriptions : Model -> Sub Msg
subscriptions model =
    updateTime (always UpdateTime)

Now, on the javascript side, you'll have to pass null as the only parameter.

app.ports.updateTime.send(null);

Update for Elm 0.19

In Elm 0.19 you had to be explicit about which Elm modules exposed ports, so you may have to update your module definition to include port module.

port module Main exposing (main)
Chad Gilbert
  • 36,115
  • 4
  • 89
  • 97
  • 1
    This works. But I wonder why there is no documentation about this on the official site? I was looking on the https://guide.elm-lang.org/interop/javascript.html#ports but there I couldn't find something about how to achieve my task (also no mention about always)... and it sucks... no books about ELM and incomplete documentation... – Buda Gavril Jan 16 '17 at 15:32
  • Yeah, it sucks that this isn't documented--I had to read Native to find out how that was called. If you're ever unsure, you can try to jump into the guts of the runtime. Note: Elm not ELM. – toastal Jan 16 '17 at 19:16
  • I might have messed something up, but does this work for 0.19? – jc00ke Jul 16 '19 at 19:04
  • 1
    Yes, this still works with Elm 0.19. [Here is a working example](https://ellie-app.com/66ZgNqYn2J2a1). The only real difference is that you have to define the module as `port module` at the top – Chad Gilbert Jul 17 '19 at 11:30