Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cancel subscriptions in Elm

Tags:

elm

I am following the Elm guide and I am at the point where I try to implement a Pause button for the clock example. In the guide it is written:

Add a button to pause the clock, turning the Time subscription off.

All I did was add a paused attribute to the model and use it in the update function. How am I supposed to cancel the subscription?

module Main exposing (..)

import Html exposing (Html)
import Html.App as App
import Html.Events exposing (onClick)
import Svg exposing (..)
import Svg.Attributes exposing (..)
import Time exposing (Time, second)


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


type alias Model =
    { time : Time
    , paused : Bool
    }


init : ( Model, Cmd Msg )
init =
    ( Model 0 False, Cmd.none )


type Msg
    = Tick Time
    | Toggle


update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        Tick newTime ->
            if not model.paused then
                ( Model newTime False, Cmd.none )
            else
                ( model, Cmd.none )

        Toggle ->
            ( Model model.time (not model.paused), Cmd.none )


subscriptions : Model -> Sub Msg
subscriptions model =
    Time.every second Tick


clock : Time -> Html Msg
clock time =
    let
        sAngle =
            turns (Time.inMinutes time)

        sHandX =
            toString (50 + 40 * cos sAngle)

        sHandY =
            toString (50 + 40 * sin sAngle)
    in
        svg [ viewBox "0 0 100 100", width "300px" ]
            [ circle [ cx "50", cy "50", r "45", fill "#0B79CE" ] []
            , line [ x1 "50", y1 "50", x2 sHandX, y2 sHandY, stroke "#023963" ] []
            ]


view : Model -> Html Msg
view model =
    let
        btnText =
            if model.paused then
                "Start"
            else
                "Pause"
    in
        Html.div []
            [ clock model.time
           , Html.button [ onClick Toggle ] [ Html.text btnText ]
           ]
like image 766
Pep. Avatar asked Aug 01 '16 22:08

Pep.


1 Answers

I guess you can simply return Sub.none instead in your subscription function when it is paused.

If you choose to do this way, then you can revert Tick handler in your update function.

subscriptions : Model -> Sub Msg
subscriptions model =
    if model.paused
    then Sub.none
    else Time.every second Tick
like image 112
Tosh Avatar answered Nov 06 '22 05:11

Tosh