node-restful icon indicating copy to clipboard operation
node-restful copied to clipboard

Handler not running when arguments.length>3

Open naugtur opened this issue 12 years ago • 5 comments

I took an example from your readme and added two arguments that I needed: (based on http://benaugarten.com/blog/2013/01/31/restful-a-better-rest-api-using-node-dot-js-with-express/)

Resource.route('moreinfo', {
    detail: true,
    handler: function(req, res, next, err, model) { //ADDED err and model
        // req.params.id holds the resource's id
        res.send("I'm at /resources/:id/moreinfo!")
    }
});

The handler never runs and therefore the situation with broken status_code occurs (as in #43)

the next() handler in express looks like this:

function callbacks(err) {
  var fn = route.callbacks[i++];
  try {
    if ('route' == err) {
      nextRoute();
    } else if (err && fn) {
      if (fn.length < 4) return callbacks(err);
      fn(err, req, res, callbacks);
    } else if (fn) {
      if (fn.length < 4) return fn(req, res, callbacks);
      callbacks();
    } else {
      nextRoute(err);
    }
  } catch (err) {
    callbacks(err);
  }
}

I guess the tutorial needs an update, because the err and model are not coming back I guess. What is the currently correct way to interact with element's model? Should I query for it in route handler now?

My current code looks like this:

Project.route('pages', ['get'], {
    detail: true,
    handler: function(req, res, next) {
        // req.params.id holds the resource's id
        Project.findById(req.params.id, function(err, model) {
            if (!model) {
                return next(restful.objectNotFound());
            }
            res.send(model.pages);
        });

    }
});

But I'm not sure if I'm not quering the same thing twice

naugtur avatar Sep 25 '13 12:09 naugtur

Is there a update on this issue? The module is excellent, just want to know how to access the object that was resolved from a custom detail route..

sharathm avatar Jun 21 '14 14:06 sharathm

Hey @sharathm

Glad you like the module. I must have missed this issue. The additional arguments used to be supported before I refactored how the middleware gets set up. In the current state, this doesn't happen.

That means that when you set up a detail route, you do have to query for the model in question. I chose that because of performance reasons too, so you don't always need to read the model in question.

baugarten avatar Jun 21 '14 15:06 baugarten

Barring a few special cases, a detail route would ideally involve some operation related to the id in question right, and so fetching that model might actually be worth the performance hit. Maybe you can provide a option preFetchModel : true and set its default to false ? Just a thought..

and also,

if chaining of the handler is allowed, then it can be great.. something like

Resource.route("recommend.post",{
 detail : true,
 handler : funcA,funcB funcC
});

where

funcA = function(req,res,next) { .. next(); }
funcB = function(req,res,next) { .. next(); }
funcC = function(req,res) { .. res.send(200); }

then for me, writing smaller functions that can be unit tested is easier. But for now, if we can somehow get the model into the handler callback, that will be great.. :ok_hand:

sharathm avatar Jun 21 '14 15:06 sharathm

I suppose that would be possible to populate the model, but I would have to think it over more.

For now, I added support for registering multiple handlers for a given route, so you can do

Resource.route('lkajsdlka', {
  handler: [function() {..}, function() {..}, ... ]
});

baugarten avatar Jun 22 '14 20:06 baugarten

excellent! many thanks.. :smile:

sharathm avatar Jun 23 '14 03:06 sharathm