-
Notifications
You must be signed in to change notification settings - Fork 67
Description
I have discovered a problem that I suspect have to do with how commands and subscriptions are scheduled. I'll try to make clear what I have found so far. And since Ellie does not support Browser.application I'll paste an SSCCE here.
module Main exposing (main)
import Browser
import Browser.Events
import Browser.Navigation
import Html exposing (Html, button, div, text)
import Html.Events exposing (onClick)
type alias Model =
{ key : Browser.Navigation.Key
, subscribeToAnimationFrames : Bool
}
type Msg
= Navigate
| UrlChanged
| AnimationFrame
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
Navigate ->
( model
, Browser.Navigation.pushUrl model.key "#foo"
)
UrlChanged ->
( { model | subscribeToAnimationFrames = True }
, Cmd.none
)
AnimationFrame ->
( { model | subscribeToAnimationFrames = False }
, Cmd.none
)
view : Model -> Browser.Document Msg
view model =
{ title = "Test"
, body =
[ button [ onClick Navigate ] [ text "Click this button to cause the problem" ]
, Html.h1 []
[ Html.text "Subscribe to animation frames: "
, Html.text (Debug.toString model.subscribeToAnimationFrames)
]
, Html.pre
[]
[ Html.text (Debug.toString model)
]
]
}
subscriptions : Model -> Sub Msg
subscriptions model =
if model.subscribeToAnimationFrames then
Browser.Events.onAnimationFrame (always AnimationFrame)
else
Sub.none
main : Program () Model Msg
main =
Browser.application
{ init = \_ _ key -> ( Model key False, Cmd.none )
, onUrlChange = always UrlChanged
, onUrlRequest = always Navigate
, view = view
, update = update
, subscriptions = subscriptions
}When the application receives the message Navigate it navigates to another url. When the browser changes url the message UrlChanged is sent to the application. When this happens the subscriptions that result from the first update gets applied after the subscriptions that result from the second update.
This means that when then UrlChanged message is sent to the application and I want to subscribe to Browser.Events.onAnimationFrame it is "cancelled" by the resulting subscriptions from the previous update. So even if model.subscribeToAnimationFrames is True there is no guarantee that the application is subscribed to Browser.Events.onAnimationFrame.
Let me know if I need to provide any more info.