Changing subscriptions when Url changes

I have a single-page app where I would like to listen for keyboard subscriptions when a certain route is selected, and I can’t figure out how this is done. I’ve recreated the problem in a simple repo based on the Elm Guide’s example Navigation app. Am I allowed to put a conditional in the subscriptions function? This is the line that breaks the keyboard listener for me.

I also put this on Ellie, but I don’t think routes are supported there so it doesn’t compile.

Yes, it’s normal to put a conditional in the subscriptions function. Here’s an example where I do it on one of my projects.

What kind of error are you getting? Does it just not work when you try to run it? Do you get a weird compiler error?

I’ve heard of there being a compiler bug that can cause things to behave strangely for complex subscriptions functions but I’ve not run into it myself so don’t have much context on it. Maybe someone else here can fill us in :slightly_smiling_face:

2 Likes

I looked through the code and I think this looks very similar to a problem I encountered. I reported it as an issue to elm/browser (https://github.com/elm/browser/issues/49) since I thought it had to do with routing somehow. It has also been reported to elm/core with a different description (https://github.com/elm/compiler/issues/1776).

1 Like

I have had severe problems with conditionals in subscriptions. They don’t work reliably. Might work in one app, but not in another. Don’t use them.

What do you propose to do when you have 20 pages each one with different subscription needs?

I think that’s an exception. That’s a case that actually works I think. I’m more thinking about subscriptions that depend on a state in the current model, that doesn’t work reliably for me. But yes, I have a case statement based on page in my main subscriptions, that works, but an if statement in there based on some property to enable something after a model change does not work reliably for me.

1 Like

Thanks everyone for your insights on this! I pushed a few updates informed by your suggestions. First, I tried removing the field in the model, and extracting the logic that had populated it to a function. This meant only the route needed to update, but this change didn’t seem to make a difference.

Next, I added a NoOp Msg constructor that has no effect when triggered, and returned that from my subscription when the route is not set to listen to the keyboard. This way, every keystroke returns a Msg. This was suggested in the bug documentation that @Carlsson87 linked.

This still didn’t seem to be working, so I installed elm-live to get debugger info about Msgs. The app will start listening for the keyboard after the first keystroke. The first one returns a NoOp, and after that, it updates the Msg it sends back. Has anyone had any luck getting things to update more eagerly?