When can msg be sent to elm through port?

const app = Elm.Main.init({
    node: document.getElementById('app')
})
app.ports.messageReceiver.send('some msg')

We can’t send msg to elm immediately after initialization, right?

So, when can? Any help(some words, a link to some doc or discussion) would be appreciated.

What are you trying to achieve? A couple of things you can do right out of the box are:

  • You can send a Msg within the app init ( Browser - browser 1.0.2 ) that is, on the Elm’s side-of-things, so it can be processed in the update function.
  • …Or you can pass a “flag” from that Elm.Main.init(...) from JS in the case you need some value available in JS world to initialise your app (Flags · An Introduction to Elm).

I just tried sending the message right away, using the port example from the docs, and it worked.

If you send a message that is the wrong type, it will get logged to the JS console and not make it to Elm. Maybe that’s what’s going on?

the official example is of course correct. But I said send msg immediately after elm.main.init. The official example don’t send msg immediately.

Thank you for your help. I want to init elm as early as possible.

but some feature is accomplished in js, and the js sdk is large. So i want to init the UI before load the js part, so that my user can see the ui first.

and once the js part is loaded and initialized, I must notify the elm part.

so i cant use flag, because i must init the elm part first. And then load and init the js part. and then notify elm: all features are ready to use. and the elm part starting accept user’s input or other reaction.

Another possibility is that you haven’t subscribed to the port on the Elm side.

More details (or especially a reproduction on ellie-app.com) would help us help you better.

You want to send a message from your JS to Elm to say that the JS is ready(?):

// JS 
elmApp.ports.notifyJS_IsReady.send(true) 
-- Elm
port module YourModule exposing (..)

-- Imports Here

{- Register the port function `notifyJS_IsReady` on the 
   ports object of your JS Elm app.
   Without this line, you can't do 
  `elmApp.ports.notifyJS_IsReady.send` in JS
   (It also needs to be used in a `subscriptions` function or the
   elm compiler will ignore it and it won't exist on the JS `ports` object)
-}
port notifyJS_IsReady : (Bool -> msg) -> Sub msg

type alias Model =
    { jsReady : Bool
    , ...
    }

type Msg 
   = JS_IsReadyMsg Bool
   | ...

update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
    case msg of 
        JS_IsReadyMsg readyOrNot ->
            ({ model | jsReady = readyOrNot }, Cmd.none)

        ...


{- Messages sent from JS via ports come in as a subscription
   The JS_IsReadyMsg is then passed to your update function with
   the value sent through the port - in this case it's a Bool.
-}
subscriptions : Model -> Sub Msg 
subscriptions model =
   if not model.jsReady then 
       notifyJS_IsReady JS_IsReadyMsg
   else 
       Sub.none

From what I understand you want, that should achieve it, though not tested :wink:

HTH

1 Like

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