Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

redirect route to another

I am trying to redirect route to another before route callback is executed. I have following piece of code:

console.log("file loaded");
(function (History) {
    var _navigate = History.prototype.navigate;

    _.extend(History.prototype, {
        navigate: function (fragment, opts) {
            alert("adad");
            return _navigate.call(this, fragment, opts);
        }
    });
})(Backbone.History);

This code wraps Backbone.History.navigate method, and showing alert on the method call. But this alert never shows up when I am changing routes.

The console.log line is just to be sure that file has been loaded after backbone.js.

What is wrong with this code?

like image 645
user606521 Avatar asked Feb 12 '13 19:02

user606521


People also ask

What is redirect in routing?

An important part of "routing" is handling redirects. Redirects usually happen when you want to preserve an old link and send all the traffic bound for that destination to some new URL so you don't end up with broken links.

What is redirecting routes in angular?

When the application start, it navigates to the empty route by default. We can configure the router to redirect to a named route by default. So, a redirect route translates the initial relative URL (”) to the desired default path.

How do I redirect a URL to another URL in react JS?

replace() method to redirect to an external url in React, e.g. window. location. replace('https://google.com') . If a certain condition is met, you can programmatically replace the current resource with the provided URL by calling the replace() method.


1 Answers

I think you're overriding the wrong thing: that navigate isn't used the way you think it is.

Let us look at part of Backbone.history.start:

// Start the hash change handling, returning `true` if the current URL matches
// an existing route, and `false` otherwise.
start: function(options) {
  //...
  if (this._hasPushState) {
    Backbone.$(window).on('popstate', this.checkUrl);
  } else if (this._wantsHashChange && ('onhashchange' in window) && !oldIE) {
    Backbone.$(window).on('hashchange', this.checkUrl);
  } else if (this._wantsHashChange) {
    this._checkUrlInterval = setInterval(this.checkUrl, this.interval);
  }

You'll see that all the various ways of handling routing in Backbone go through checkUrl rather than navigate. The checkUrl method does a bit of busy work and calls loadUrl; one part of the busy work is this:

  if (this.iframe) this.navigate(current);

so navigate will be called but only when an <iframe> is being used to simulate hashchange and popstate events and AFAIK that only happens when you're using an older version of IE.

Back to the usual path through the code. We've seen that checkUrl does some busy work and calls loadUrl so what does that do? loadUrl does this:

loadUrl: function(fragmentOverride) {
  var fragment = this.fragment = this.getFragment(fragmentOverride);
  var matched = _.any(this.handlers, function(handler) {
    if (handler.route.test(fragment)) {
      handler.callback(fragment);
      return true;
    }
  });
  return matched;
}

If you look at the route method in History and the route method in Route you'll see that handler.callback is what calls the route handler from one of your routers and triggers the routing event.

The navigate method that you're replacing is pretty much only used by Router's navigate:

navigate: function(fragment, options) {
  Backbone.history.navigate(fragment, options);
  return this;
}

If you want to redirect before the route handler is called, you could replace loadUrl with something like this:

(function(History) {
    var _loadUrl = History.prototype.loadUrl;
    _.extend(History.prototype, {
        loadUrl: function() {
            var args = [].slice.apply(arguments);
            args[0] = this.getFragment(args[0]);
            // If args[0] is the fragment that you want to
            // redirect then replace it here or do whatever
            // needs to be done.
            return _loadUrl.apply(this, args);
        }
    });
})(Backbone.History);

Demo: http://jsfiddle.net/ambiguous/e4KYK/

Overall I think you'd be better off handling the redirect in a normal route handler: when the offending route is called, just call navigate on whatever router is handy.


Keep in mind that Backbone.History isn't documented beyond the start method so everything here is subject to change.

like image 167
mu is too short Avatar answered Oct 07 '22 02:10

mu is too short