
This is the fifth post in a series of posts about Elm for JavaScript developers. If you're a JavaScript developer, and you want to know more about Elm, stay tuned to this series of posts or sign up for DailyDrip and check out all the episodes we have in our room topic.
Here is what we already see:
Today we will see how to deal with external inputs in our application, and how to deal with side effects in Elm.
Subscriptions are data coming from some external source. Commands are data that we send to the runtime to request it to do something for us that interacts with the outside world and send us back a message telling us how it went. Our very known update function perform request for the runtime to perform an action for us.
Subscriptions

Subscriptions allow us to listen to the outside world and turn things that happen into Msg inside our app. - Adams, Josh
Probably you already saw subscriptions when you were creating your Elm program.
main : Program Never Model Msg
main =
program
{ init = init
, view = view
, update = update
, subscriptions = subscriptions
}
When we are not using subscriptions, we can use always Sub.none.
main : Program Never Model Msg
main =
Html.program
{ init = init
, update = update
, view = view
, subscriptions = always Sub.none
}
Subscriptions are the way our application can listen for external inputs.
External inputs like:
- Keyboard events
- Mouse movements
- Browser location changes
- Websocket events
- Timer events
Example 1 of Subscription
Let's see an example from the documentation about Subscriptions. We will
subscribe to the keyboard and mouse.
Model
Our model is just an integer.
Messages
Our Messages will be:
- MouseMsg Mouse.Position
- KeyMsg Keyboard.KeyCode
So, these are the way the USER interacts with our app, in this case using the
Mouse and the Keyboard.
These messages will be produced by our subscriptions, and we can handle them in our update.
Our Subscriptions
Subscriptions allow us to listen to the outside world and turn things that happen into Msg inside our app. In our case, we
will have two subscriptions: one from our keyboard and another from our mouse.
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.batch
[ Mouse.clicks MouseMsg
, Keyboard.downs KeyMsg
]
Using
Sub.batch
allow us to listen a list of Subscriptions.
Once something happen in one of these subscriptions, they are turned into Msg, which we then deal with in our update function. deal with this in our update function.
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
MouseMsg position ->
( model + 1, Cmd.none )
KeyMsg code ->
( model + 2, Cmd.none )
If our Msg comes from mouse, we will increment our model by 1. If it comes from
our keyboard, we will increment by 2.
Our Entire code:
import Html exposing (Html, div, text, program)
import Mouse
import Keyboard
-- MODEL
type alias Model =
Int
init : ( Model, Cmd Msg )
init =
( 0, Cmd.none )
-- MESSAGES
type Msg
= MouseMsg Mouse.Position
| KeyMsg Keyboard.KeyCode
-- VIEW
view : Model -> Html Msg
view model =
div []
[ text (toString model) ]
-- UPDATE
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
MouseMsg position ->
( model + 1, Cmd.none )
KeyMsg code ->
( model + 2, Cmd.none )
-- SUBSCRIPTIONS
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.batch
[ Mouse.clicks MouseMsg
, Keyboard.downs KeyMsg
]
-- MAIN
main : Program Never Model Msg
main =
program
{ init = init
, view = view
, update = update
, subscriptions = subscriptions
}
You can see this example in the Ellie
App. This is a simple example on how to
use subscriptions.
Example 2 of Subscription
As a second example of using Subscription, we will use the code from the last
blog post, about bitcoin price.
subscriptions : Model -> Sub Msg
subscriptions model =
Time.every second (always GetBitcoinPrice)
Here we are using
always.
It is one of the Basics things from Elm. The function always will return
always the same value.
So, just changing this in our last Elm program, it will make the HTTP request
each second. Easy, right? Rather than constantly polling, we could listen to a websocket for price updates as well. These would use subscriptions too.
Commands

Commands are data we send to the runtime to request it to do something for us that interacts with the outside world and send us back a message telling how it went. - Adams, Josh
In our last program, we have used Commands. Commands let us make HTTP
requests, generate random numbers, etc.
We use commands a lot, probably more than subscriptions.
Functions with side effects
In theory, function with side effects are forbidden in the language. Although,
we need to have functions with side effects. Elm uses the concept of commands to
handle this.
A function returns a command value which names the desired side effect.
So, every time, from now on, when you see a function returning a command, you
will know this function has a side effect! However, this isn't the whole story. We're just describing a side effect, so it's still a pure function. The Elm runtime takes the data describing the side effect and performs it for us, ensuring that it's safe and keeping us from dealing with potential errors. This is just one more way Elm makes it easy to write applications with zero runtime errors.
Let's see some examples in the documentation:
generate : (a -> msg) -> Generator a -> Cmd msg
send : (Result Error a -> msg) -> Request a -> Cmd msg
All these functions result in side effects happening in the runtime, as they return commands.
Summary
Today we saw what are Commands and Subscriptions in Elm and how they are used.
Resources