When Do You Set The URL, In A BackboneJS App?


Oscar Godson recently asked a question about when to set the URL in a Single Page App (Backbone, specifically):

I have a sidebar that pops in with form. It has a URL for it since it’s so commonly used. Going to app.com/foo/add would load the page and open the sidebar. Another view, TopMenu, has a button to open the sidebar. My question: who triggers the URL change? Should RightSidebar change the URL withBackbone.navigate (w/o trigger) or should the button change the URL and call the RightSidebar‘s openmethod?

There are a lot of possibilities for an answer, here. Oscar already alluded to several different options and there are potentially more. In my reply, I bring up a subject that I’ve talked about a lot – how to effectively use a router in a SPA. This topic is relevant to the question, but only one angle from which to view the problem. Ultimately, we’re looking for a single place in the code that can be in control of the application’s context and/or state – one place to rule them all, and in the router bind them … or something like that.

My Reply (With A Bit Of Formatting)

Any time you have multiple points of entry for the same behavior, you need to encapsulate that behavior’s kick-off in to a single thing… an object, a function, a single line of code… whatever that thing is, it needs to be the one thing that is called in order to produce the desired behavior and state of the application. This often means you have to do a lot of prep work to get the application in to a state where that one thing can be called. But, once you’re there you just call that one thing and the application puts itself in to the expected state with the expected behavior.

Here is a simple example:

In both cases (using the router or clicking the DOM element), the code all comes back to the doFoo function. This is the one place in the application that knows how to put the app in to the “foo” state. In your case, this puts sidebar in place and puts the route in the URL as expected.

At this point, it doesn’t matter what code kicks off the `doFoo` process / app state. It could be a router, a button in a menu, a websockets event, image recognition technology from a webcam or anything else. When the doFoo function is called, the app moves in to the right state and does it’s thing, including setting the URL.

Of course this gets complicated when you start talking about very large apps. In very large apps, you need to partition your apps based on context to keep things sane. Sometimes it will make sense for a button click to just call a method on an object and the app is good to go. But, sometimes the feature being requested is in a completely different context with a completely different layout in the app. In these cases, it’s often easier to have a button click call router.navigate(“foo”, true)” to force the route handler to fire, or just use a link with the real url in the link.

In the end, the principle still applies: no matter how many entry points there are, you only want to call the `doFoo` function in order to get the app into the right state, with the right URL in the address bar.

Further Reading

I’ve alluded to a lot of things in this reply, and a handful of assumptions about application architecture. There is a lot of information that you may want to read up on, some of which is free and some of which is not. But if you’re interested in seeing how this works out, in the end, it’s worth your time and money.

There are probably dozens or hundreds more resources that I could list here, but that would be a very long list to compile.

Group By Count With MongoDB And MongooseJS