3

I'm trying to conditionally block a route from being accessed. I think this can be done with guardRoute: http://durandaljs.com/documentation/Router/

function guardRoute(routeInfo, params, instance) : object - Before any route is activated, the guardRoute function is called. You can plug into this function to add custom logic to allow, deny or redirect based on the requested route. To allow, return true. To deny, return false. To redirect, return a string with the hash or url. You may also return a promise for any of these values.

I'm not sure how to specify which route should be accessed though, or how to re-route to another view if I need to deny access. Can someone post an example of its use in this manner?

BenMorel
  • 34,448
  • 50
  • 182
  • 322
SB2055
  • 12,272
  • 32
  • 97
  • 202

2 Answers2

6

You should use guardRoute before activating the router e.g. in shell.js. The example is taken from a Durandal 2.0 alpha site. AFAIK guardRoute hasn't changed from 1.2, but setting a breakpoint will allow you to figure out what arguments are passed in for 1.2. As a general rule, return true to allow navigation, false to prevent it and a hash or url value to redirect.

define(['plugins/router'], function (router) {

    // Redirecting from / to first route in route.map
    router.guardRoute = function(routeInfo, params, instance){
        if (params.fragment === ''){
            return routeInfo.router.routes[0].hash;
        }
        return true;
    };
    ...    

    return {
        ...
        router: router,
        activate: function () {
            router.map([
               ---
            ]);

            return router.activate();
        }
    };
});
RainerAtSpirit
  • 3,723
  • 1
  • 17
  • 18
  • If possible, can we change the title of this question so that it is easier to find? I often link back here because people can't find this question, it's one of those 'I don't know what I don't know' scenarios. I am going to propose an edit. – PW Kad Aug 04 '13 at 21:06
  • Hey @PWKad - what what would you like it changed to? – SB2055 Oct 28 '13 at 19:53
  • @SB2055 Something like 'handle / ignore bad route durandal' – PW Kad Oct 28 '13 at 20:48
1

I am a newbie to durandaljs 2.0 having only used it for a couple of weeks so this was one of my first stumbling blocks. see my code below

router.guardRoute = function (routeInfo, params, instance) {
    var insecureRoutes = ['login', 'terms','signup','password'];
    if ($.inArray(params.fragment, insecureRoutes) || mymodule.isAuthenticated()) {
        return true;
    } else {
        return 'login/' + params.fragment;
    }
};

I also define a route for the login page like this

{ route: 'login/(:returnroute)', moduleId: 'viewmodels/login', nav: false },

This allows you to optionally specify a return rout so that after login you can redirect the user to where ever it is they were initially trying to go to. I hope it helps someone

Obi
  • 3,091
  • 4
  • 34
  • 56
  • thanks! this was really useful for my own project. I just had some minor edits with the logic and the naming scheme :) – Paul Jul 20 '14 at 22:44
  • 1
    Hi Paul, glad to hear that this helped you. I think you misunderstood the 'naming scheme; the insecure routes are routes which do not require authentication i.e. are publicly accessible hence the name 'insecure'. As for the proposed edit for the $.inArray function, while you are right it does return an integer and you could test for that but in javascript type coercion -1 is false see http://www.ecma-international.org/ecma-262/5.1/#sec-9.2. Cheers – Obi Jul 21 '14 at 08:46
  • Hey Obi, I see, the naming issue is a matter of perspective I guess. Noted on the coercion thing as well :) Thanks! – Paul Jul 21 '14 at 15:20