How to mix types in Elm

I’m stuck a point where I want to display a list from a submodule that produces an output of type “Element Msg” along with data from the main module that produces also “Element Msg”. The issue is that the Msg in both cases is of different types. How do I mix both types?

I would really appreciate your help.

Best regards

Maybe Element.map can help:

https://package.elm-lang.org/packages/mdgriffith/elm-ui/latest/Element#map

Something like:

import Module

type MainMsg = FromModule Module.Msg | AMainMsg | AnotherMainMsg

mainElement : Element MainMsg
mainElement =
  Element.map FromModule Module.yourElement

Where Module.yourElement is an Element Module.Msg.

If that makes any sense?

Thanks for hinting me in the right direction and providing an example. I was able to use Element.map resolve the issue.
Based on this question I would like to know how to best change the model (state) within a submodule. For this I would have to call the update of the submodule from the main. Or should basically only one model (state) be used in the Main?

I don’t know if it’s the best way, but one way to do it is the following pattern where you have a State, init, Msg and update in your module and using them in main like this:

import Module

type alias Model =
    { moduleState : Module.State }


init : Model
init =
    { moduleState = Module.init }


type Msg
    = FromModule Module.Msg


update : Msg -> Model -> Model
update msg model =
    case msg of
        FromModule moduleMsg ->
            { model
                | moduleState =
                    Module.update
                        moduleMsg
                        model.moduleState
            }
1 Like

Thank you so much for your help, I really appreciate it. I refactored my code based on your proposal.

I set up a subscription within my submodule. Do you have a recommendation on how to call subscriptions from the Main?

I’ve never had a subscription function outside main. But I guess you could use
https://package.elm-lang.org/packages/elm/core/latest/Platform-Sub#batch
and
https://package.elm-lang.org/packages/elm/core/latest/Platform-Sub#map
to do something like:

import ModuleA
import ModuleB

type Msg = FromA ModuleA.Msg | FromB ModuleB.Msg

subscriptions : Model -> Sub Msg
subscriptions model =
   Platform.Sub.batch 
      [ Platform.Sub.map FromA ModuleA.subscription model.statusA
      , Platform.Sub.map FromB ModuleB.subscription model.statusB
      ]

…but I doubt it’s advisable. The note on Platform.Sub.map seems to think it is seldom useful in “well-structured Elm code”. But I’m not sure what a better alternative looks like.

I see your point and decided to only export (Model, Msg(..), init, update, view) from my submodules. This means that I had to move subscriptions from submodules to Main.

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.