RedGiant
RedGiant

Reputation: 4748

chaining database queries using promise in node.js

I'm trying to use the spread method to accumulate promised results that I've read in this thread with Q.js. It works in another block of code but not in the following app.get example. I want to chain queries using Sequelize and mongoose and pass all the returned data to the spread method. Here's my attempt:

var db = require('./db/managedb'); // Sequelize
var mongo_models = require('./db/mongo_model')(mongoose);
var WB = mongo_models.Webdata,
Est = mongo_models.Estimate;

app.get('/p/:tagId', function(req, res){ 
   var filename = req.param("tagId");
   var mysql = db.db.query('CALL procedure()').then(function(rows) {
      console.log(rows);
   });  // Sequelize

   var nosql = WB.find().exec(function(err,k){
      console.log(k);
   }) // Mongoose

   var nosql2 = Est.find().exec(function(err,la){
      console.log(la);
   }) // Mongoose

   Q.try(function(){
       return mysql
    }).then(function(mysqls){
       return [ mysqls,nosql]
    }).then(function(mysqls,nosqls){
       return [mysqls,nosqls,nosql2]
    }).spread(function(mysqls,nosqls,nosql2s){
       res.render(filename+'.html', {my:mysqls,wb:nosqls,est:nosql2s}) 
    }).catch(function(error){ 
       console.log('fail')   
   })
})

I'm just getting a blank page with Cannot GET /p/5 and there's no "fail" shown in the console.log. Here's my original code that works, but it's suffering from callback hell.

app.get('/p/:tagId', function(req, res){ 
   var filename = req.param("tagId");
   db.db.query('CALL procedure()').then(function(rows) {
     WB.find().exec(function(err,wb){
       Est.find().exec(function(err,est){
         res.render(filename+'.html', {my:rows,wb:wb,est:est}) 
       }) 
     })
  }).catch(function (error) {
     console.log('own: database error');
   })
})

Upvotes: 1

Views: 1181

Answers (1)

Benjamin Gruenbaum
Benjamin Gruenbaum

Reputation: 276306

You can try using them as proxies:

app.get('/p/:tagId', function(req, res){ 
   var filename = req.param("tagId");
   var rows = db.db.query('CALL procedure()');
   var wb = WB.find().exec();
   var est = Est.find().exec();
   Promise.props({my: rows, wb: wb, est: est}).then(function(obj){
       res.render(filename+'.html', obj) 
   }).catch(function (error) {
     console.log('own: database error'); // not sure I'd just supress it
   });
});

Bluebird is already available through sequelize if you don't have it in your project.

Alternatively, you don't have to put them in specific variables:

app.get('/p/:tagId', function(req, res){ 
   var filename = req.param("tagId");
   Promise.props({
       my:  db.db.query('CALL procedure()'), 
       wb: WB.find().exec(), 
       est: Est.find().exec()
   }).then(function(obj){
       res.render(filename+'.html', obj); 
   }).catch(function (error) {
     console.log('own: database error'); // not sure I'd just supress it
   });
});

Upvotes: 1

Related Questions