How to hook Cmd when user leaving a page in SPA?

I have a url like /devices/1 , route to Page.Device

After user entered this page, I subscribe to a WebSocket channel with id 1 through ports.

But now I need to unsubscribe this channel if user left this page. By clicking an a tag or by casting a Nav.pushUrl .

I currently think about onUrlChange in Main , and considering doing it in stepUrl.

Since the declaration of both ports under Page.Device , is there a more elegant way to have a destruct Cmd? On opposite of Page.Device.init .

I’m looking for something may behave like this in React hooks:

useEffect(() => {
  return // destruct function
}, [])

I end up add an exit function to every page with the help of added Global.Msg .

Then, let onUrlChange call the exit function but not entering new page immediately.

The exit function casts a Global.StepUrl msg after destruction completed which will finally enter new page.

Main.elm

-- UPDATE
    case ( message, model.page ) of
        ( UrlChanged url, Login login ) ->
            Login.exit url login |> updateWith Login LoginMsg model -- updateWith just do some Cmd.map

        ( GlobalMsg (Global.StepUrl url session), _ ) ->
            stepUrl url session model -- Init new page

Page/Login.elm

exit : Url.Url -> Model -> ( Model, Cmd msg, Cmd Global.Msg )
exit url model =
    ( model, Cmd.none, (cast (Global.StepUrl url model.session)) )
    -- Or we can just return ( model, destructCmd, Cmd.none) and cast Global.StepUrl after received destruction complete message.
2 Likes

Great, good hack, thanks for sharing !!

1 Like

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