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 1
to cast aNav.pushUrl
to 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.pushUrl
works 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.