Search code examples
elm

Elm update infinite loop


New to Elm, so I may be missing something obvious.

I'm working on an Elm application that uses annaghi/dnd-list. I'm encountering an infinite loop of calls to update. This happens when clicking on one element, then another one. Here's the code:

config : DnDList.Config Player
config =
    { beforeUpdate = \_ _ list -> list
    , movement = DnDList.Free
    , listen = DnDList.OnDrag
    , operation = DnDList.Swap
    }


system : DnDList.System Player Msg
system =
    DnDList.create config DndMsg


type alias Model =
    { navKey : Nav.Key
    , room : WebData Room
    , dnd : DnDList.Model
    , startError : Maybe String
    }

type Msg
    = RoomReceived (WebData Room)
    | DndMsg DnDList.Msg

...

update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        RoomReceived room ->
            ( { model | room = room }, Cmd.none )
        DndMsg message ->
            let
                room = model.room
            in
            case room of
                RemoteData.Success actualRoom ->
                    let
                        ( dnd, players ) =
                            system.update message model.dnd actualRoom.players

                        updatedRoom = RemoteData.map 
                            (\roomData -> 
                                { roomData | players = players }
                            ) room
                    in
                    ( { model | dnd = dnd, room = updatedRoom }
                    , system.commands model.dnd
                    )
                _ ->
                    ( model, Cmd.none )

When I change the line system.commands model.dnd to Cmd.none, then there is no infinite looping call to the update function, but also nothing happens. The message that keeps getting called in the dnd-list library is GotDropElement (Ok dropElement)

Again, new to Elm, so this may be a poorly formed question, but any help is appreciated.

Thanks!


Solution

  • Figured it out. Had to add a subscription to listen to mouse events

    
    currentSubs : Model -> Sub Msg
    currentSubs model =
        case model.page of
            GameRoomPage pageModel ->
                GameRoom.subscriptions pageModel
                    |> Sub.map GameRoomMsg
            _ ->
                always Sub.none model
    
    ...
    
    main : Program () Model Msg
    main =
        Browser.application
            { view = view
            , init = init
            , update = update
            , subscriptions = currentSubs
            , onUrlRequest = LinkClicked
            , onUrlChange = UrlChanged
            }