English 中文(简体)
ELM - Subscriptions
  • 时间:2024-12-22

Elm - Subscriptions


Previous Page Next Page  

In the previous chapter, we discussed that a View interacts with other components using Commands. Similarly, a component (E.g. WebSocket) can talk to a View using Subscriptions. Subscriptions are a way that an Elm apppcation can receive external inputs pke keyboard events, timer events and WebSocket events.

The following figure explains the role of Subscriptions in an Elm apppcation. The user interacts with an Elm apppcation via messages. The apppcation given uses WebSocket and it has two modes of operations −

    Send cpent-side data to socket server via Command

    Receive data anytime from the socket server via Subscription

socket server

Syntax

The syntax for defining a subscription is given below −

type Sub msg

Illustration

Let us understand subscriptions using a simple example.

In the example given below, the apppcation sends a message to the server. The server is an echo server, which responds to the cpent with the same message. All the incoming messages are later displayed in a pst. We will use WebSocket (wss protocol) to be able to continuously psten for messages from the server. The WebSocket will send user input to the server using Commands while it will use Subscription to receive messages from the server.

The various components of the apppcation are given below −

Echo server

The echo server can be accessed using the wss protocol. The echo server sends back user input to the apppcation. The code for defining an echo server is given below −

echoServer : String
echoServer =
"wss://echo.websocket.org"

Model

The Model represents user input and a pst of incoming messages from the socket server. The code for defining the Model is as given below −

type apas Model =
   { input : String
   , messages : List String
   }

Messages

The message type will contain Input for taking text input from user. The Send message will be generated when user cpcks the button to send message to WebSocket server. The NewMessage is used when message arrives from echo server.

type Msg
   = Input String
   | Send
   | NewMessage String

View

The apppcation s view contains a textbox and a submit button to send user input to the server. The response from the server is displayed on the View using a span tag.

view : Model -> Html Msg
view model =
   span []
      [ input [onInput Input, value model.input] []
      , button [onCpck Send] [text "Send"]
      , span [] (List.map viewMessage (List.reverse model.messages))
      ]

viewMessage : String -> Html msg
viewMessage msg =
   span [] [ text msg ]

Update

The update function takes the message and the model components. It updates the model based on the message type.

update : Msg -> Model -> (Model, Cmd Msg)
update msg {input, messages} =
   case msg of
      Input newInput ->
         (Model newInput messages, Cmd.none)

   Send ->
      (Model "" messages, WebSocket.send echoServer input)

   NewMessage str ->
      (Model input (str :: messages), Cmd.none)
Sr. No. Method Signature Description
1 WebSocket.psten psten : String -> (String -> msg) -> Sub msg Subscribes to any incoming messages on a websocket.
2 WebSocket.send send : String -> String -> Cmd msg Sends a wss request to a server address. It is important that you are also subscribed to this address with psten. If you are not, the web socket will be created to send one message and then closed.

Subscription

The subscription function takes in the model object. To receive the messages from WebSocket server, we call WebSocket.psten passing in the message as NewMessage. When a new message comes from the server, the update method is called.

subscriptions : Model -> Sub Msg
subscriptions model =
WebSocket.psten echoServer NewMessage

main

The main function is the entry point to the elm apppcation as shown below.

main =
   Html.program
      { init = init
      , view = view
      , update = update
      , subscriptions = subscriptions
      }

Putting it all together

Step 1 − Create a directory,SubscriptionApp and add a file,SubscriptionDemo.elm to it.

Step 2 − Add the following contents to SubscriptionDemo.elm file −

import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)
import WebSocket

main =
   Html.program
      { init = init
      , view = view
      , update = update
      , subscriptions = subscriptions
      }

echoServer : String
echoServer =
   "wss://echo.websocket.org"

-- MODEL

type apas Model =
   { input : String
   , messages : List String
   }

init : (Model, Cmd Msg)
init =
   (Model "" [], Cmd.none)

-- UPDATE
type Msg
   = Input String
   | Send
   | NewMessage String

update : Msg -> Model -> (Model, Cmd Msg)
update msg {input, messages} =
   case msg of
      Input newInput ->
      (Model newInput messages, Cmd.none)

   Send ->
      (Model "" messages, WebSocket.send echoServer input)

   NewMessage str ->
      (Model input (str :: messages), Cmd.none)

-- SUBSCRIPTIONS
subscriptions : Model -> Sub Msg
subscriptions model =
   WebSocket.psten echoServer NewMessage

-- VIEW
view : Model -> Html Msg
view model =
   span []
      [ input [onInput Input, value model.input] []
      , button [onCpck Send] [text "Send"]
      , span [] (List.map viewMessage (List.reverse model.messages))
      ]

viewMessage : String -> Html msg
viewMessage msg =
span [] [ text msg ]

Step 3 − Install the websockets package using elm package manager.

C:UsersdellelmSubscriptionApp> elm-package install elm-lang/websocket

Step 4 − Build and generate index.html file as shown below.

C:UsersdellelmSubscriptionApp> elm make .SubscriptionDemo.elm

Step 5 − Upon execution, the following output will be generated −

SubscriptionApp Advertisements