Search code examples
javascriptnode.jscallbackcouchdbcouchdb-nano

callbacks and returns with CouchDB and nano.js


I'm trying to write a small library with re-usable database calls with nano.

db.view('list', 'people', function(error, data) {
  if (error == null) {
    res.render('people/index', {
      people: data.rows
    });
  } else {
    // error
  }
});

That can get quite messy when having multiple requests:

db.view('list', 'people', function(error, people) {
  db.view('list', 'items', function(error, items) {
    db.view('list', 'questions', function(error, questions) {
      db.view('list', 'answers', function(error, answers) {
        ...
        res.render('people/index', {
          people: people.rows,
          items: items.rows,
          questions: questions.rows
          ...

So, the idea was to create a function:

var getPeople = function() {
  // do db calls here and return
}

res.render('people/index', {
  people: getPeople()
});

But that doesn't work.

How can I solve this and put everything into an external node-js-module.js file?


Solution

  • You got some great answers here already.

    From the nano source code you have an example that might help:

    Also if you don't really understand how nodejs flow control works I can't recommend enough that you see this tutorial:

    Better than using a tool is to use the tool understanding how it works :) Maybe you'll end up just coding your own control flow, that's what most of us ends up doing anyway.

    Hope this helps, attached code for convenience.

      var db    = require('nano')('http://localhost:5984/emails')
        , async = require('async')
        ;
    
      function update_row(row,cb) {
        var doc = row.doc;
        delete doc.subject;
        db.insert(doc, doc._id, function (err, data) {
          if(err)  { console.log('err at ' + doc._id);  cb(err); }
          else     { console.log('updated ' + doc._id); cb(); }
        });
      }
    
      function list(offset) {
        var ended = false;
        offset = offset || 0;
        db.list({include_docs: true, limit: 10, skip: offset}, 
          function(err, data) {
            var total, offset, rows;
            if(err) { console.log('fuuuu: ' + err.message); rows = []; return; }
            total  = data.total_rows;
            offset = data.offset;
            rows   = data.rows;
            if(offset === total) { 
              ended = true;
              return; 
            }
            async.forEach(rows, update_row, function (err) {
              if(err) { console.log('something failed, check logs'); }
              if(ended) { return; }
              list(offset+10);
            });
        });
      }
    
      list();