I am trying to add subscriptions as I have a dropdown, this helps ensure that the dropdowns automatically close when you click outside of them. On doing so, I had to change the model
as well as my update
.
This link (will take you to the Elm Bootstrap site) is the dropdown I am working with which is using Bootstrap 4.
Error I am getting
The 1st argument to
sandbox
is not what I expect:295| Browser.sandbox 296|> { init = initialModel 297|>
, update = update 298|> , view = view 299|> }This argument is a record of type:
{ init : ( Model, Cmd Msg ) , update : Msg -> Model -> ( Model, Cmd Msg ) , view : Model -> Html Msg }
But
sandbox
needs the 1st argument to be:{ init : ( Model, Cmd Msg ) , update : Msg -> ( Model, Cmd Msg ) -> ( Model, Cmd Msg ) , view : ( Model, Cmd Msg ) -> Html Msg }
Alias Model
type alias Model =
{ currentNumber : Int, clicks : Int, outputList : List(String), uniqueValues : Dict Int Int, firstNumber : String, secondNumber : String, myDropState : Dropdown.State, items : List String, selectedItem : String, dictKeyToRemove : String,
modalVisibility : Modal.Visibility }
Initial Model
initialModel : (Model, Cmd Msg)
initialModel =
({ currentNumber = 0, clicks = 0, outputList = [""], uniqueValues = Dict.empty, firstNumber = "", secondNumber = "", myDropState = Dropdown.initialState, items = ["Small", "Medium", "Large"], selectedItem = "Small", dictKeyToRemove = "",
modalVisibility = Modal.hidden }, Cmd.none)
Main
main : Program () Model Msg
main =
Browser.sandbox
{ init = initialModel
, update = update
, view = view
}
Subscriptions
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.batch
[ Dropdown.subscriptions model.myDropState DropMsg ]
Update
update : Msg -> Model -> ( Model, Cmd Msg)
update msg model =
case msg of
DropMsg state ->
({model | myDropState = state }, Cmd.none)
I am not sure what I am missing at this point, I have tried changing the argument with no luck.
Browser.sandbox
will create a simple and very limited program. The dropdown requires capabilities beyond that, namely subscriptions, which means you need to use either Browser.element
or Browser.document
instead.
The type of Browser.element
is:
element :
{ init : flags -> ( model, Cmd msg )
, view : model -> Html msg
, update : msg -> model -> ( model, Cmd msg )
, subscriptions : model -> Sub msg
}
-> Program flags model msg
Compared to Browser.sandbox
:
sandbox :
{ init : model
, view : model -> Html msg
, update : msg -> model -> model
}
-> Program () model msg
There are three differences here:
init
takes an argument, flags
, which can be anything and will be interpreted by the runtime according to its type. For your purpose just using ()
should be enough (which is essentially what sandbox
does), but see the flags section of the guide for more details.
init
and update
returns ( model, Cmd msg )
instead of just model
. This is the root cause of your error, because you have update
and init
functions which return ( model, Cmd msg )
as element
would expect, but try to feed them to sandbox
. This makes the compiler unhappy, because it thinks that model
should be ( Model, Cmd msg )
instead of just Model
.
element
expects an additional subscriptions
function, which you have defined but currently aren't doing anything with since sandbox doesn't accept it.
Putting this all together, substituting the following main
function should work for you:
main : Program () Model Msg
main =
Browser.element
{ init = \() -> initialModel
, update = update
, view = view
, subscriptions = subscriptions
}