Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Subroute fails if called before Backbone.history has been started #3

Open
carpeliam opened this issue May 9, 2012 · 10 comments
Open

Comments

@carpeliam
Copy link
Contributor

I tried initializing a subroute within the initialize of my main router, and this works fine if I start at the root and browse to a route covered by my subroute, but doesn't work if I load a subroute-related path initially. (So, if my subroute covers '#books' and I start at www.books.com and navigate to www.books.com/#books everything is fine; but if I load up www.books.com/#books in my browser, it throws an exception.) The reason for this is that Backbone.history.loadUrl references options.root which won't exist until after Backbone.history.start has been called. And I can't start Backbone.history before I've created my router either. This is with Backbone v0.9.2.

Your initial approach was to create the subroute in a handler of the main router, but I'm getting a stack overflow with that approach in IE (at least IE8, I think IE9 as well). I'll create a separate issue for that.

@patrixd
Copy link

patrixd commented Jul 10, 2012

I have the same problem. Did you fix the problem?

@patrixd
Copy link

patrixd commented Jul 10, 2012

I have changed
var hash = Backbone.history.getHash();
to
var hash = Backbone.history.fragment;

And now It works

@remkoboschker
Copy link

Hi,

I had the same issue and solved it by creating the subrouter in a handler of the main router. However this introduces a new problem. When I take a look at the Backbone.history object, I notice that when I reload the page with the url of any of the subroutes (except the empty subroute), that the handlers for the subroutes are no longer there!

For example in the main router:
routes: {
"": "index",
"records": "getRecords",
"records/": "getRecords"
},

getRecords: function () {
if (!this.recordsRouter) {
this.recordsRouter = new RecordsRouter("records");
}
}

In the subrouter:
routes: {
"": "showAllRecords",
":id": "showRecord"
}

When I go to localhost:8080/#records
and then to localhost:8080/#records/1
there is no problem (Backbone.history shows the subrouter handlers)

but when I go to localhost:8080/#records/1 again
then the subroutes are not triggered (Backbone.history does not show any subroute handlers)

reloading localhost:8080/#records does not cause any problems

Going straight to localhost:8080/#records/1 also does not trigger the subrouts (handlers not there) which probably comes down to the same thing as reloading.

Any suggestions?

@remkoboschker
Copy link

Hello again,

It looks like I managed to get it sorted. In the piece of code that get called before anything else I have added:

app.router = new Router(); // this is the main router
Backbone.history.start({pushState:false, root: "/");
app.recordRouter = new RecordRouter({createTrailingSlashRoutes: true}); // this is the subrouter

I'll let you know if I run into any problems.

@kfigiela
Copy link

kfigiela commented Aug 1, 2012

I don't use lazy loading and I couldn't get it working until I commented these lines:

        // grab the full URL
        // var hash = Backbone.history.getHash();

        // Trigger the subroute immediately.  this supports the case where 
        // a user directly navigates to a URL with a subroute on the first page load.
        // Backbone.history.loadUrl( hash );

I initialize subrouters in main router initialize and do Backbone.history.start after app and routers are initialized. Seems to work well!

@moderndegree
Copy link

I do lazy load my sub-routers and I discovered that having a catch-all in my sub-routers fixes the issue for me.

routes: {
"*hash" : "handleCatchAll"
}

@geekdave
Copy link
Contributor

Hi all,

The procedure I've been using is:

  1. Initialize a vanilla Backbone.Router to handle your base routes
  2. Call Backbone.History.start()
  3. Initialize SubRouters, either manually or automatically as part of a base route (for example, the first time someone navigates to "/books" you could have a main Router callback that initializes the Books SubRouter if not already initialized)

I, too, have noticed that #3 must come after #2. In my workflow this isn't a problem. Let me know if there are specific use cases that make this workflow problematic for anyone, and if possible include some code samples.

Also I just checked in a Jasmine test suite, so in the future it would be great to see a failing test spec for any reported issues. If I don't hear back on this issue in a couple weeks, I'll go ahead and close it with the above steps as the recommended course of action.

@geekdave
Copy link
Contributor

Robin Wenglewski notifications@github.com
2:19 AM (8 hours ago)
@geekdave I stumbled across this, too. It works with the workflow you
describe. However, I think usability will be greatly enhanced if we get it
to work so that initializing SubRouters works in Router.initialize.
This seems like the intuitive place for creating SubRouters.

Thanks Robin. I have considered creating an extension of Backbone Router
called BaseRouter whose purpose would be intended to create subrouters
based on the first part of a navigation path. I'm pretty swamped at work
so it might be awhile until I can get to this. In the meantime if you'd
like to help take a crack at the coding, I'd welcome a pull request.

Just noticed that your comment appears to have been deleted from the issues
list for some reason, so I've quoted your comment above.

Thanks,
Dave

On Tue, Nov 13, 2012 at 2:19 AM, Robin Wenglewski
notifications@github.comwrote:

@geekdave https://github.com/geekdave I stumbled across this, too. It
works with the workflow you describe. However, I think usability will be
greatly enhanced if we get it to work so that initializing SubRouters works
in Router.initialize. This seems like the intuitive place for creating
SubRouters.


Reply to this email directly or view it on GitHubhttps://github.com//issues/3#issuecomment-10320044.

@mohitmayank
Copy link

i just tried it myself and getting the same issue. too deep and too tight so cant put more details right now. but wudnt it be a good idea to somehow check if the history is not started and start it in the constructor of subroute?

@evandegr
Copy link

I've noticed a little bit of strange behavior that I believe is related to this issue.

If I load a sub route i.e. 'route/sub' right off the bat, I notice that the subrouter does not get called. However, if I add an initialize onto my subrouter and do some kind of action there like a simple console.log, it DOES work.

// this code works
app.SocialStream.Router = Backbone.SubRoute.extend({
        initialize : function(){
            console.log('test');
        },
        routes: {
            'new' : 'newSocialStreamDashboard',
        },

        newSocialStreamDashboard : function() {
            alert('hells yes');
        }
    });
// this code doesn't
app.SocialStream.Router = Backbone.SubRoute.extend({
        routes: {
            'new' : 'newSocialStreamDashboard',
        },

        newSocialStreamDashboard : function() {
            alert('hells yes');
        }
    });
// this code also doesn't
app.SocialStream.Router = Backbone.SubRoute.extend({
        initialize : function(){

        },
        routes: {
            'new' : 'newSocialStreamDashboard',
        },

        newSocialStreamDashboard : function() {
            alert('hells yes');
        }
    });

Any idea why that might happen?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants