elm-style-animation icon indicating copy to clipboard operation
elm-style-animation copied to clipboard

Problem Cmd.mapping from child module

Open playfulThinking opened this issue 8 years ago • 4 comments
trafficstars

I'm an Elm newbie so perhaps I'm doing something wrong, but I think there's a problem.

I am doing animations in Main and in my ZombificationStatus (don't ask!) child component. I was successfully animating in both until I needed to use Animation.Messenger.send in Main. I made the changes you specify in the documentation:

In both modules, I import Animation import Animation.Messenger

and my models have something like this: slidingOutStyle : Animation.Messenger.State Msg

The problem I am having is mapping the messages from my child to parent. If I don't map, I (understandbly) get:

-- TYPE MISMATCH -------------------------------------------------- src/Main.elm
The right side of (::) is causing a type mismatch.
677|                                         model.slidingOutStyle :: pageStyles)
                                                                                          ^^^^^^^^^^
(::) is expecting the right side to be a:
    List (Animation.Messenger.State Main.Msg)
But the right side is:
    List (Animation.Messenger.State ZombificationStatus.Msg)

--

So I try to map it:

mapToMain : Animation.Messenger.State Msg -> Animation.Messenger.State Msg
mapToMain thing =
    case thing of
        Animation.Messenger.State zombificationMsg ->
            Animation.Messenger.State (Cmd.map ZombificationStatus zombificationMsg)

and I get this compiler error:

-- NAMING ERROR --------------------------------------------------- src/Main.elm

Cannot find pattern `Animation.Messenger.State`.

681|         Animation.Messenger.State zombificationMsg ->
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
No module called `Animation.Messenger` has been imported.

-- NAMING ERROR --------------------------------------------------- src/Main.elm

Cannot find variable `Animation.Messenger.State`.

682|             Animation.Messenger.State (Cmd.map ZombificationStatusPage zombificationMsg)
                            ^^^^^^^^^^^^^^^
`Animation.Messenger` does not expose `State`.

Am I doing something wrong, or is there a problem here?

(perhaps this? https://github.com/elm-lang/error-message-catalog/issues/215 )

Thanks!

playfulThinking avatar Aug 25 '17 20:08 playfulThinking

Hello! lol, ZombificationStatus, I love it.

Ok, so the first thing is that the Animation.Messenger.State constructor isn't exposed by the library, meaning you can use it in type signatures, but you can't unpack it in a case statement.

And also, the library doesn't expose a map function (which, to be honest, is an oversight by me).

If you're only using Messenger.send in the Main lib, I think the way forward would be to try to make Animation.Messenger.State ZombificationStatus.Msg a Animation.Messenger.State Main.Msg, without mapping.

I believe you can do just by changing the type annotation where you're defining it.

mdgriffith avatar Aug 25 '17 21:08 mdgriffith

Thanks for the super-quick response!

If I understand you correctly, you are asking me to change the type annotation in my model. Then the problem (for me!) is that the child defines its own animation styles, and stores them in model defined in the child:

type alias Model = { animationStyles : Animation.Messenger.State Msg , animationStyles2 : Animation.Messenger.State Msg }

I can't change Msg to Main.Msg here, because this module is imported by Main, so writing Main.Msg causes a dependency cycle.

I could, of course, move these styles to Main, but my app is an SPA (actually, a Cordova app), will have a few dozen pages, and I'd like to follow how Richard Feldman did things in his RealWorld example app https://github.com/rtfeldman/elm-spa-example. I'd rather not have all of the sub-pages models coalesced into a monster Main model.

Or did I misunderstand you?

playfulThinking avatar Aug 25 '17 21:08 playfulThinking

Yeah, I'm a big fan of the spa example by Richard :)

Hmmm,

Can you switch the type annotations to something like Animation.Messenger.State msg?

type alias Model msg =
     { animationStyles : Animation.Messenger.State msg
     , animationStyles2 : Animation.Messenger.State msg
     }

I'm not %100 if that will work...

mdgriffith avatar Aug 26 '17 03:08 mdgriffith

Tried it. I ended up having to make dozens of changes as that change flowed through my program, LOL, and after fixing all but one (which I'm not sure was fixable), noticed this:

-- TYPE MISMATCH -------------------------------------------------- src/Main.elm

The right side of (::) is causing a type mismatch.


675|                                         model.slidingOutStyle :: pageStyles)
                                                                      ^^^^^^^^^^
(::) is expecting the right side to be a:

    List (Animation.Messenger.State Main.Msg)

But the right side is:

    List (Animation.Messenger.State msg)

... which is, essentially, where we started from! So it looks like it doesn't, in the end, solve the problem. :(

Thanks for trying though! Any other ideas? If not, might you be able to support mapping, sometime in the not-too-distant future?

playfulThinking avatar Aug 28 '17 20:08 playfulThinking