marciovicente.filho
marciovicente.filho

Reputation: 159

Trouble with promises bluebird in node.js

I have a module in node.js, that connect with postgres database through sequelize lib. My module code basically is:

// ofr-network/index.js
var requireDir = require('require-dir');
var models = requireDir('./models');

var network = {
  getReportsFromCity: function(cityId) {
    models.index.reports.findAll({
      where: { id: cityId },
      attributes: ['id', 'latitude', 'longitude']
    }).then(function(reports) {
      console.log('[NETWORK-OFR] Get reports from %s', cityId);
      return reports;
    }).catch(function(err){
      console.log('Error getting reports from %s', cityId);
      console.log(err);
    });
  }
}

module.exports = network;

Well, this code works fine. Now I'm trying use this module in my express application, importing and calling this method, but this code isn't return anything. I've searched, and see that I must to use promises, once this code above is async. My API method code is below:

var express = require('express');
var app = express();
var router = express.Router();
var network = require('ofr-network');
var Promise = require('bluebird');

router.get('/', function(req, res) {
  var getReports = Promise.promisify(network.getReportsFromCity, network);
  getReports(538).then(function(reports) {
    console.log('DONE');
    // this print isn't running
  }).catch(function(err){
    console.log(err);
  });
  res.render('index.html', { title: 'Title page' });
});

module.exports = router;

Someone can help me?

Upvotes: 2

Views: 435

Answers (2)

Benjamin Gruenbaum
Benjamin Gruenbaum

Reputation: 276286

Promises represent a value + time. Promises have state, they start as pending and can settle to:

  • fulfilled meaning that the computation completed successfully.
  • rejected meaning that the computation failed.

Functions that return promises (like sequelize functions) let you hook on those promises with then that runs when the previous promise fulfilled. You can chain promises (like you've done) but don't forget to return them to the outside. Promises utilize return values for hooks.

Promise.promsify takes a function that takes a callback in the (err, data) format - it is not necessary in your code that already uses promises. It's useful for promisification which is not the case here.

Instead - you just need to return the promise so you can use it:

var network = {
  getReportsFromCity: function(cityId) {
    return models.index.reports.findAll({ // NOTE THE RETURN
      where: { id: cityId },
      attributes: ['id', 'latitude', 'longitude']
    }).then(function(reports) {
      console.log('[NETWORK-OFR] Get reports from %s', cityId);
      return reports;
    }).catch(function(err){
      console.log('Error getting reports from %s', cityId);
      console.log(err);
    });
  }
}

Which would let you do:

network.getReportsFromCity(538).then(function(data){
    console.log("Data", data);
});

Don't forget that promises do not convert asynchronous code to synchronous code and are just a useful tool - not magic :) Everything outside the promise chain can still happen before the chain itself runs. Your res.render is misplaced - you need to put it in the final then with the relevant data.

Upvotes: 3

ChinKang
ChinKang

Reputation: 4342

could you try to put line res.render('index.html', { title: 'Title page' }); after line console.log('DONE'); ? It seems the response were called before you get to the getReports result.

Upvotes: 0

Related Questions