Code Monkey home page Code Monkey logo

director's Issues

Initialization always fires 'notfound' handler

The Router init() method executes a call to route() without passing a parameter. This causes the route to be 'undefined' which ultimately causes a call to the notfound handler upon initialization.

// init method
this.init = function() {
listener.init(route);
route();
return this;
};

//in parse method
if(route === undefined && path.length === 0) {
self.noroute(partialpath);
return false;
};

Is the initial route() call necessary? Should the 'notfound' handler be added only initialization? That seems clunky.

Thanks!

Routes recurse

Say I have two routes: /blogpost and /blogpost/edit. Currently, if /blogpost/edit is hit, the "on" function for both the routes are called. There might be use-cases for both to be called, but the majority of use-cases will be entirely different functionality, so recursing the child urls is not expected. /blogpost will show the blog post, and /edit will show a form, for example.

If there already is a way to control if the recursion will happen, I'm not aware of it. If there isn't, there should be. :)

Let me know if I wasn't clear enough.

router.get(/\//, handler) breaks

What I'm trying to do is match against the root directory ("/").

It's entirely possible that this shouldn't work, but if so the way to match against a root directory (using .get and friends) is non-obvious.

Overlapping simple tokens issue

If you have overlapping route that include simple tokens, only the routes that END in a simple token will be routed. No errors are displayed or callbacks are hit.

The routes are listed below:

'/foo/:id' : function(){
            console.log("foo2 ", arguments);
        },

        '/foo/:id/bar' : function(){
            console.log("bar", arguments);
        },
        '/foo/:id/bar/:id2' : function(){
            console.log("bar2", arguments);
        },

        '/foo/:id/bar/:id2/baz' : function(){
            console.log("baz", arguments);
        },
        '/foo/:id/bar/:id2/baz/:id3' : function(){
            console.log("baz2", arguments);
        }

Use director programmatically ( without CLI or HTTP or browser )

Is it currently possible to use director entirely in memory? Without needing any external interface?

We were attempting to use an API that looked like this:

var router = new director.Router();

router.on(/foo/, function () {
  console.log('sup');
});

router.dispatch('GET', '/foo', function (err) {
  console.log('sup', err);
});

Leave function won't fire on hashchange

First, let me say, great library. Exactly what I think this world needs :)

Im having a little issue. when I navigate away from a certain page, i have leave event, and it just won't fire. Is there something specific I need to do?

Problem with regex matching "\/"

Code example:

router.get(/sup/meh/, function () {
this.res.writeHead(200, { 'Content-Type': 'text/plain' })
this.res.end('hello world\n');
});

If I try to access: /sup/meh, I get this error:
/usr/local/lib/node_modules/director/lib/director/router.js:420
match = path.match(new RegExp('^' + exact));
^
SyntaxError: Invalid regular expression: /^/sup/: \ at end of pattern
at new RegExp (unknown source)
at [object Object].traverse (/usr/local/lib/node_modules/director/lib/director/router.js:420:26)

I've debugged a little bit and came to the conclusion that the problem is:
if (path.source) { // ~ line 200
path = path.source
}

The problem is when we split based on the '/' delimiter, the parts become:
'sup', 'meh'.. and when later on it tries to match 'sup' it obviously says there's a regex error.

My current quick fix: (Replacing / by /)
if (path.source) {
path = path.source.replace('/', '/');
}

Hope it helps

HTTP routing functions getting passed the route?

Either this is a bug in the code or in the docs. Should the route name be available to the registered function? Right now it's coming out as undefined.

From the docs:

function helloWorld(route) {
  this.res.writeHead(200, { 'Content-Type': 'text/plain' })
  this.res.end('hello world from (' + route + ')');
}

When running the demo code and hitting curl http://localhost:8080/hello, the print statement comes out as:
hello world from (undefined)

Can't match ";" or "/" with a wildcard in routes

Director can not match these characters because regifyString will replace route wildcards with another regexp which does not match these characters.

The following server responds to /foo/bar with "hello world", but will 404 for /foo/bar;baz or /foo/bar/baz.

var union = require('union');
var director = require('director');
var router = new director.http.Router();

router.get(/\/foo\/(.*)/, function () {
  this.res.writeHead(200, { 'Content-Type': 'text/plain' })
  this.res.end('hello world\n');
});

var server = union.createServer({
  before: [
    function (req, res) {
      var found = router.dispatch(req, res);
      if (!found) {
        res.emit('next');
      }
    }
  ]
});

server.listen(9090);

Multiple Routers and URL params

Looks like if I try to make multiple routers (like in Sammy.js) the second one overrides/disables the first. Any chance of adding support for multiple concurrent routers?

http routing recurse doesn't work

Either settings 'backword' or 'forward' don't work in http routing.

My env:

$ node -v
v0.6.6
$ npm list
├── [email protected]

Example code:

  var http = require('http'),
      director = require('director');

  var router = new director.http.Router(
  {
    '/hello':
    {
      '/hello2':
      {
        get: function(route)
        {
            this.res.write('hello2\n');
        }
      },
      get: function(route)
      {
        this.res.write('hello\n');
      }
    }
  }).configure(
  {
    recurse: 'backward',
    before: function(){ this.res.writeHead(200, { 'Content-Type': 'text/plain' }); },
    on: function(){ this.res.end(); }
  });

  var server = http.createServer(function (req, res) {
    router.dispatch(req, res, function (err) {
      if (err) {
        res.writeHead(404);
        res.end();
      }
    });
  });

  server.listen(8080);

Result:

$ curl http://localhost:8080/hello/hello2
hello2

Better Examples

Need to write some better examples of how SugarSkull works.

Bump current master version and publish ??

First of all: A happy and good coding new year! :-)

And 2nd, is there a possibility for someone to bump the version on master and publish that new version to NPM? Need the query parameter fix thats already committed two weeks ago but not published yet.... ;-)

Thanks !!

Trailing slashes not possible in director routes?

In theory, these two URLs are equally valid, and will generally mean the same thing:

  1. http://localhost:7000/api/
  2. http://localhost:7000/api

However, it seems that number 1 is not currently possible with Director.

I have this setup in my Flatiron app:

// In app.js
var flatiron = require('flatiron'),
    app = flatiron.app;

app.use(flatiron.plugins.http);

app.router.path('/api', require('./api').router);


// In api/index.js
var router = function () {
  this.get('/', function () {
    this.res.writeHead(200, { 'Content-Type': 'text/plain' });
    this.res.end('This is the entry point for the Ardon API.');
  });
};

module.exports = {
  router: router
};

I've tried different variations of that with slash or not slash in the app.router.path() and this.get() invocations, but the result is invariably the same. http://localhost:7000/api works as it should, http://localhost:7000/api/ returns the text “undefined” with a 404 not found header.

Readme link missing

You can find a browser-specific build of director here which has all of the server code stripped away.

The text here links to the front page of the repo and not to the alluded to browser-specific version

Routing for a non-match

I have the following in my application:

new Router({
    '/(\\w+)\\/' : selectRepository 
}).init();

function selectRepository(repo) {
    ...
}

I would like to match #/AAA, or #/BBB,.... However, if I put no hash, to hit the main page originally, as in http://localhost:8080/context/ it goes through the router, and in the parse method of SS.js, the first line (parse.shift) returns undefined. Then the method continues on and undefined becomes /undefined/ in leftovers, which matches my regular expression, but of course the routing will not work. I could of course check for undefined in my selectRepository function, but I really think this case should be handled internally and /undefined should not be handled as an acceptable case.

To fix this locally, I just added:

  if (partialpath === undefined) {
      return false;
  }

after

 var partialpath = path.shift(); 

of the parse method.

That said, this is probably just treating the symptom. I have not really delved in to understand all of the code, so, maybe something like:

leftovers = (partialpath ? ('/' + partialpath + '/') : '/') + path.join('/');

would be more correct.

Anyway, I am not a regex guru and so I could just have something wrong with my regex, or just be missing something in the usage entirely, as I just barely started using SugarSkull, so if there is a better way, please let me know.

'/:page': ':page'

Router({
  '/:page': ':page'
}).use({ 
  resource: {
    pizza: function() { ... },
    taco: function() { ... },
    muffins: function() { ... }
  }
})

this would be handy as it would save me from doing something redundant like this:

var pages = {
  pizza: function() { ... },
  taco: function() { ... },
  muffins: function() { ... }
}

Router({
  '/:page': {
    on: function(page) {
      pages[page]()
    }
  }
}).use({ 
  resource: pages
})

IE8 regex routing

so the following two routes work in FF, Chrome, IE9, etc.

'/test\\/': function(){console.log('test hit')},
'/test\\/([a-z0-9-]+)': function(x){console.log('test hit with '+x)}

but only the first one works when my browser is put into "Document Mode: IE8 Standards"
i am partially suspecting regex differences ( http://stevenlevithan.com/demo/split.cfm )

my current project has an IE8+ requirement. is this something you would be willing to look into? i do understand that coding for old quirks is sometimes more hassle than its worth.

SIDENOTE: as i was testing different patterns i learned that this route works in all browsers:

'/foo': { '/bar': function(){console.log('FUBAR')} }

but this one does not work in any browsers:

'/foo/bar': function(){console.log('FUBAR')}

is this the designed/desired behavior?

example code doesn't work.

encountered many problems, trying what was in the readme.

Router({})
TypeError: Object #<Object> has no method 'configure'
    at /home/dominic/source/dev/experiement/node_modules/sugarskull/lib/sugarskull/router.js:124:8
    at /home/dominic/source/dev/experiement/node_modules/sugarskull/lib/sugarskull/http/index.js:14:21
    at Object.<anonymous> (/home/dominic/source/dev/experiement/ss.js:4:9)
    at Module._compile (module.js:411:26)
    at Object..js (module.js:417:10)
    at Module.load (module.js:343:31)
    at Function._load (module.js:302:12)
    at Array.<anonymous> (module.js:430:10)
    at EventEmitter._tickCallback (node.js:126:26)

new Router({}).init()
TypeError: Object [object Object] has no method 'init'
    at Object.<anonymous> (/home/dominic/source/dev/experiement/ss.js:9:4)
    at Module._compile (module.js:411:26)
    at Object..js (module.js:417:10)
    at Module.load (module.js:343:31)
    at Function._load (module.js:302:12)
    at Array.<anonymous> (module.js:430:10)
    at EventEmitter._tickCallback (node.js:126:26)
var Router = require('sugarskull').http.Router
  , http = require('http')

function respond () {
  console.error('it worked')
  this.res.writeHeader(200); this.res.end('aoneuhaoenuhoneiurkpborkbropkbr')   
}

var r = new Router({
  on: respond,
  '/\//': respond,
  '/': respond,

})

http.createServer(function (req, res) {
  r.dispatch(req, res, function (err) { throw err })
}).listen(8080)
                                        ^
Error: Could not find path: /
    at [object Object].dispatch (/home/dominic/source/dev/experiement/node_modules/sugarskull/lib/sugarskull/http/index.js:60:16)
    at Server.<anonymous> (/home/dominic/source/dev/experiement/ss.js:21:5)
    at Server.emit (events.js:67:17)
    at HTTPParser.onIncoming (http.js:1134:12)
    at HTTPParser.onHeadersComplete (http.js:108:31)
    at Socket.ondata (http.js:1029:22)
    at Socket._onReadable (net.js:677:27)
    at IOWatcher.onReadable [as callback] (net.js:177:10)

this needs working examples!

Routing event support for request/response

Wanted to implement http basic auth checking as a filter and I'm not able to using routing events.

Request and response objects are not available to routing events and according to the comments in the routing events code, we should not return anything from a routing event function.

recursion when used with webshims

When used alongwith webshims we get the error "too much recursion", specifically on firefox 3.6.23 .
Here is jsfiddle http://jsfiddle.net/zfTBS/1/ .

I have tried with latest versions of all libs but no luck. jquery(1.6.4), webshims (1.8.2) and SugarSkull latest.

I am not sure whether webshims/SugarSkull so might add same issue for webshims too.

Same thing works well on Chrome.

Thanks for this wonderful library. We love it.

Not totally clear how to use state from README

I think I'd like to use state for something I'm working on, but it's not very clear how to do this from the documentation. Basically I have a small app with two routes:

'/builds': {
  '/:buildid': {
    on: function(buildid) { ... }
    '/jobs': {
      '/:jobid': {
        on: function(buildid, jobid) { ... }
      }
    }
  }
}

The second is a superset of the first (that is, the first one should be loaded before the second). I can make this happen by recursing forward. So far so good. The problem is that when going backward (e.g. transitioning from /builds/foo/jobs/bar to /builds/foo), SugarSkull think it needs to call the "on" function for /builds/foo (when in fact it's already loaded). I'm gathering that this is something that I can use state for, but it's not clear to me how from the documentation.

Problem 1: How do I access the state dictionary from inside my router functions?
Problem 2: How do I assign route-specific information (e.g. a buildid in the example above) to a state dictionary?

this when using a resource

Hi,

I've got a question on how to handle this in the following (browser) scenario.

var MyApp = function(){
}

MyApp.prototype.start = function() {
console.log(this);
};

var app = new MyApplication();

routes = {
'/': 'start',
}

Router(routes).configure({resource:app}).init();

When I point my browser to "#/" start gets called, but the console.log(this) prints the a.Router object.

Is there a way to get this' set to the resource?

Thanks

[build 1.0.7] Adhoc routing in browser broken

I wanted to use this adhoc routing but it seems te be broken... How is this possible btw? We're creating builds that are not working correctly :S

See commit ef3b3bf.

Adhoc routing results in Uncaught TypeError: Cannot call method 'concat' of undefined

Global Routes

The ability to add global routes to be fired whenever any part of the hash contains the fragment

e.g.

router = Router({

    '*/global/*: {
        on: killDog
    },
    '/home': {
        on: goHome,
        '/users': {
            on: loadUser
        }
    }

}).init();

would match...

http://someapp.com/#/global/

http://someapp.com/#/home/users/global/

http://someapp.com/#/home/global/users/

similarly, if you could define it as global part of a subsequent route

router = Router({

    '/home': {
        on: goHome,
        '/users': {
            on: loadUser
        },
        '*/global/*: {
            on: killDog
        }
    }

}).init();

Would match

http://someapp.com/#/home/users/global/

http://someapp.com/#/home/global/users/

http://someapp.com/#/home/users/:token/global

but not

http://someapp.com/#/global/

http://someapp.com/#/some-other-route/global/

It would be beneficial to pass the before and after fragments via arrays

e.g.

function killDog([ before, match, fragments], [after, match, fragments]  ){

}

Not sure if I'm missing something but I have tried to achieve a similar result using regex and recurse, to no avail.

Addition of query string parameters causes existing/previously working routes to no longer fire.

Original URL that worked:
http://localhost:3201/games/PS3/MostPopular/All%20PS3%20Games

'/:platform/:filter/([^.]*)': {
get: function (platform, filter, category) {
renderer.getGameslist(filter, platform, category.replace(/&/g, '%26'), 1, 20, this.req, this.res);
}
},

When I add query string parameters like in the following URL , the above route no longer is triggered.
http://localhost:3201/games/PS3/MostPopular/All%20PS3%20Games?pageNumber=2&pageSize=20

HTML5 History API Support

Feature Request: Support for HTML5 History API on an opt-in basis, with graceful fallback to hash version in lame browsers. Similar to the backbone and sammy routers. The main use case is for web apps that also want SEO (think twitter) and that build a server side solution for it. With Node being able to run your front end's same backbone models and templating it's not much more work. Having the option to handle the routing in sugarskull would be nice.

Http Router doesn't work with URL parameters

When testing with: http://development:9090/test/foo?test=test the attached route function to /test/foo isn't executed. But if I change the request to http://development:9090/test/foo it is.

I debugged the code and found that the whole URL (+ the parameters after ?) is fed into the traverse function by the dispatch function. If I change that to only the part before ? then it works. Can make a patch for it but don't know if the current behavior is the correct one. If this is the correct behavior then what do I need to do to get URLs with parameters working with Director?

with recurse on After is fired on On

for the router setup

router =Router( {
    'foo':{
        on: function(){},
        after: function(){}
    }
}).use({ recourse: forward }).init();

and the url:

#/foo

After will fired when the url is navigated to, and once the url has left.

Parameter dictionary support

So as I mentioned (too briefly) on twitter the other day, I think it
would be really neat if SugarSkull supported parameters to its URLs.
The main motivation for this is that the application I'm currently
working on (http://brasstacks.mozilla.com/gofaster/#/) has some views
that can take many parameters, for example:

http://brasstacks.mozilla.com/gofaster/#/executiontime/build/30
http://brasstacks.mozilla.com/gofaster/#/executiontime/test/60

In this example, only really the first part of the path
(executiontime) is really modelling a resource in my application. The
other two are more like parameters to the request. Obviously putting
them as fully fledged paths works (as that's what I'm doing right
now), but has the following disadvantages:

  1. It complicates the links I make on the main page (instead of just
    using defaults)
  2. More importantly, if I want to add an additional parameter (which
    I'm actually about to do), any previous links I made using the old
    structure will be invalidated.

I can think of a few ways around the above but they seem excessively
complicated. What I'm thinking of is adding the option of setting
parameters to sugar skull "URLs", so you could make queries like this:

http://brasstacks.mozilla.com/gofaster/#/executiontime
http://brasstacks.mozilla.com/gofaster/#/executiontime?type=build
http://brasstacks.mozilla.com/gofaster/#/executiontime?type=build&range=30

and the router would only parse the section up to the '?' character,
passing the set of parameters to the function as a dictionary called
params (if there are no parameters, the dictionary would obviously be
empty).

I guess this would break backwards compatibility since we'd now be
expecting the parameters variable to appear in everybody's functions
(but at least all people would have to do is update their code:
existing URLs would still work on the client side).

If I were to add something like that to a fork of your project, would
you accept it back into mainline?

Routing table created incorrectly when passed to the constructor

I've copied the sample code from the docs and added a little logging.

https://gist.github.com/1367702

After starting the server, http://localhost:8080/hello, the route passed to the constructor on lines 20 and 21, returns a 404.

The logging statement on line 47 prints the routing table which is broken for the routes passed to the constructor. For a method it seems to have "et" instead of "get".

data:   {
data:       bonjour: { get: [Function] },
data:       hello: {
data:           et: { on: [Function] }
data:       },
data:       hola: { get: [Function] }
data:   }

This is using Node 0.6.1 and SugarSkull version 1.0.1 from npm.

Multiple hash parameters

Is there a way to handle multiple hash parameters?

eg.
...index.html#/roadmap/7/2010

I tried to define it this way:
'/roadmap': {
   '/(\d+)': {
       on: displayRoadmap,
       '/(\d+)': {
           on: displayRoadmap
       }
   }
}

Hoping that it would call my function with one or two parameters based on matches:
function displayRoadmap(id, year) {
   ...
}

Thanks,
tvalletta

Nested syntax with params

Would like to be able to define nested routes that support simple-tokens or regexps, pass all values forward.

'/a': {
   '/(\d+)': {
       on: function(b) { ... },
       '/(\d+)': {
           on: function(b, c) { ... }
       }
   }
}

Error when router.on() (Client-side routing)

using: director-1.0.7.min.js

In chrome v16:

var router = new Router().init();
router.on('/:some', function () {...}); //=> TypeError: Cannot call method 'concat' of undefined

In FF v9

var router = new Router().init();
router.on('/:some', function () {...}); //=> TypeError: this.scope is undefined

In IE v9 does not work.

Simple Tokens

@hij1nx I'm wondering if you'd be open to the idea of simple tokens. Here's what I mean:

Say you want to match the group name and project name from this URL: /project/mobile-team/iphone-app

With Regex

'/project\\/([a-z0-9-]+)\\/([a-z0-9-]+)': viewProject

With Simple Params

'/project/:group/:project': viewProject

Your readme mentions that simple tokens like this can't handle every situation, and that's true. But they handle probably 95% of the use cases for routing, and they're very easy to use. I'm sure that's why Express, Sammy, and CouchDB use them. Actually the only thing you gain from regex routes is the ability to distinguish from /articles/4 and /articles/four for example. But the increase in power comes at the cost of being more difficult to use.

I have an idea for a simple syntax that would allow both simple params AND regex distinction where you need it. Just include the regex filter after the simple param. So for example using the same URL /project/mobile-team/iphone-app you could:

Match any param

'/project/:group/:project': viewProject

Match only params of a certain type (with regex)

'/project/:group/:project(\\d+)': viewProject 
//would match /project/mobile-team/43 but not /project/mobile-team/iphone-app

The (\\d+) isn't a capture, but rather a definition of what type the simple param must be in order to match. What do you think? This lets your routes be simple and concise, and only use regular expressions in the rare cases where you need them. This would make sugarskull.js easier to use for developers (like me) who aren't experts with regular expressions, without losing any of the flexibility that sugarskull.js currently has.

If you're interested but don't have the time would you be open to a pull request for this?

Thanks!

Stack overflow / event firing order

My mini-router here:
https://gist.github.com/1248332

Having 2 issues:

  1. my global 'after' event seems to be firing before 'on'
  • this was happening with the sample code from the SugarSkull dl too
  • what exactly does "after this route" mean? i.e. does this mean when another hashchange happens when you are already on the specified route?
  1. Getting a stack overflow error with regify on line 38 of SS.js when I try to use the resource param and define a methods object
  • this was happening for me on both Chrome and FF

Maybe I'm just defining something wrong?

ps. can you also specify what SS.min.js is? doesn't seem to just be a minified version of SS.js, or am I wrong?

Allow routing without the hash

Currently client-side director only supports hash-routing. It would be a nice sugar feature if it could support regular routing too.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.