baseprime / grapnel

The smallest JavaScript router with named parameters, HTML5 pushState, and middleware support
http://grapnel.js.org
468 stars 40 forks source link

Duplicate match issue #9

Closed Botnary closed 10 years ago

Botnary commented 11 years ago

I have two different routes that match both. Is there a way to fix the regex not to match both ? For example:

<script>
    var router = new Grapnel.Router();
    // Create route
    router.get('calendar/:year/:month/:day', function(req){        
        console.log(req.params);        
    });
    router.get('calendar/project/edit/:id', function(req){
        console.log(req.params);
    });
</script>

For this requests #calendar/project/edit/10 i have to matches and the log output will be

{
    day: "10"
    month: "edit"
    year: "project"
}

and

{
    id: "10"
}

when i am expecting it to be just {id: "10"} but it matches the first route too.

baseprime commented 11 years ago

@Botnary This is because by using /calendar/:year you're telling it to match any route beginning with /calendar. Instead, you could use RegExp like this:

var router = new Grapnel.Router(),
    firstRoute = /calendar\/project\/edit\/([0-9]+)/,
    secondRoute = /calendar\/([0-9]+)\/([0-9]+)\/([0-9]+)/;

router.get(firstRoute, function(req){
    var id = req.params[0];
    console.log(req.params);
});

router.get(secondRoute, function(req){  
    var year = req.params[0],
        month = req.params[1],
        day = req.params[2];

    console.log(req.params);
});

Or, you could increase the level of the date in the URL. For example, you could add view before specifying the date thusly:

router.get('calendar/view/:year/:month/:day', function(req){        
    console.log(req.params);
});

router.get('calendar/project/edit/:id', function(req){
    console.log(req.params);
});

This will tell the router to only match the first route if calendar/ is followed by view/

Botnary commented 10 years ago

Excellent, this little library is very flexible, that's what i want. Thanks!