According to Structure · An Introduction to Elm , I made my sub page looks like this pseudo code:
(The point is that in order to use Nav.pushUrl in sub page, I saved Nav.Key in both main Model and Session . If I remove Nav.Key from Model, elm-hot will report key location changed.)
Main.elm
type alias Model =
{ key: Nav.Key
, page: Monitor Monitor.Model
}
type Msg =
MonitorMsg Monitor.Msg
-- Cmd.map Monitor msg
Monitor.elm
type alias Model =
{ session: { key: Nav.Key } }
type Msg =
DeviceIdChanged Int
Say, if DeviceIdChanged 1 , I need to use Nav.pushUrl key to load my url to /monitor/1
I currently pass key to session during Monitor.init , but:
- If I add a blank line to my source code, which triggers an elm-hot reload, then cast the
DeviceIdChanged 1to cast aNav.pushUrlto re-step into my page.
The init cmds in my page will not be casted, and open the debugger will spam these errors in console:
Uncaught TypeError: Cannot read properties of undefined (reading 'childNodes')
at _VirtualDom_addDomNodesHelp (eval at hmrApply (runtime-900e2ded8fe2c4a1.js:322:16), <anonymous>:2448:34)
-
If I avoid the elm-hot reload (by not modifying my source code), the
Nav.pushUrlworks fine. -
If I use a
a [href "monitor/1"] []to triggeronUrlRequest = LinkClicked, it also works fine even if I modified source code and after triggered elm-hot reload.
So I guess maybe something broken while I use Nav.pushUrl key which takes key from Monitor.Model session, which different from main Model key.
Is there another elegant way to share global Model state or cast global Msg in sub page? (Different with session which potentially change Nav.Key location)
Or if dumping all pages into Main.elm is a better solution, why the structure guide is teaching us this technology, both in package.elm-lang.org and elm-spa-example ?
– UPDATE
I can confirm that introducing a GlobalMsg thus let Main.elm handle Nav.pushUrl using Model key can solve this problem.