user4893295
user4893295

Reputation: 651

Correct way to pass an object through to a callback?

In this example, using express, I want to pass through the 'res' so I can direct the page when the functions are complete:

function dostuff(id) {
  console.log(id);
};

app.post('/:id', function(req, res){
  dostuff(req.params.id, function() {
    res.redirect('/');
  });
});

But 'res' isn't known. So I have tried to pass it into the function arguments with:

dostuff(req.params.id, function(res) {

but that doesn't work. How should one do this correctly?

EDIT

So I appear to have lost the context in simplifying the code to an example. This is my original code - note the 'res' being passed through, but the error generated is that res.redirect is not a function:

app.delete('/todo/:id', function(req, res){
  var id = [req.params.id];
  couch.view('items', 'all_items', {keys: id}, function(err, body, res) {
    if (!err) {
      var row = body.rows[0];
      var id = row.id;
      var rev = row.value.rev;
      couch.destroy(id, rev);
      res.redirect('/todo');
    };
  });
});

Upvotes: 0

Views: 89

Answers (2)

Ruan Mendes
Ruan Mendes

Reputation: 92274

When you define your callback as function(err, body, res), you are expecting the couch.view to pass res as the last argument, but it's not passing it.

In your case, you should just remove res from the argument list so that you are not shadowing res that had been available from the closure.

app.delete('/todo/:id', function(req, res){
  var id = [req.params.id];
  couch.view('items', 'all_items', {keys: id}, function(err, body) {
    // Don't define a res argument to this callback, use it from the closure
    ...
    res.redirect('/todo');
  });
});

Answer to the original question

Your doStuff needs to take a callback, in your case, you don't need to pass it through because it's available through the closure.

function dostuff(id, cb) {
  console.log(id);
  // Faking doing something async
  setTimeout(cb, 1000);
};

app.post('/:id', function(req, res){
  dostuff(req.params.id, function() {
    // res is available from the closure
    res.redirect('/');
  });
});

Here's another solution in case your callback is not defined inline.

function dostuff(id, cb) {
  console.log(id);
  // Faking doing something async
  setTimeout(function, 1000);
};

function afterFinished(res) {
   res.redirect('/');
}
app.post('/:id', function(req, res){
  dostuff(req.params.id, afterFinished.bind(null, res));
});

Upvotes: 1

Josef32
Josef32

Reputation: 38

You can bind the res to the callback like below:

dostuff(req.params.id, (function(res) {
    res.redirect('/');
}).bind(this, res));

Upvotes: 0

Related Questions