How to use Model.query() with promises in SailsJS/Waterline?
Asked Answered
O

4

11

I'm having issues with Sails.JS 0.9.8. I would like to use promises with the Model.query() function (I use sails-mysql adapter).

This code will work :

User.findOne({ email: email })
.then(function(user) {
  console.log(user);
});

but this one won't

User.query("SELECT email FROM user WHERE email = ?", [ email ]))
.then(function(err, rows) {
  console.log(rows);
})

I get undefined for both 'err' and 'rows'.

Is it just not implemented or I am doing something wrong ? If not implemented, is there any alternative to use promises with .query() ?

Thank you in advance

Obregon answered 19/2, 2014 at 16:35 Comment(0)
K
25

You can promisify(User.query) yourself, just like you'd do for any other callback-based API, like:

var Promise = require('bluebird');

....

var userQueryAsync = Promise.promisify(User.query);
userQueryAsync("SELECT email FROM user WHERE email = ?", [ email ])
.then(function(user) {
    console.log(user);
});
Katrinka answered 6/11, 2014 at 0:23 Comment(2)
Very nice-- we're now linking here from the reference page from .query() in the sails docs.Maggot
I get only node_modules/sails-mysql/node_modules/mysql/lib/protocol/Parser.js:77 throw err; // Rethrow non-MySQL errors ^ RangeError: Offset is out of boundsDevries
M
4

As a hack you can monkeypatch all your models in bootstrap like this

module.exports.bootstrap = function(cb) {
    var Promise = require('bluebird');

    Object.keys(sails.models).forEach(function (key) {
        if (sails.models[key].query) {
            sails.models[key].query = Promise.promisify(sails.models[key].query);
        }
    });

    cb();
};
Melonie answered 7/12, 2015 at 18:37 Comment(0)
V
3

The query method is specific to sails-mysql, and doesn't support deferred objects the way that the more general Waterline adapter methods (e.g. findOne, find, create, etc) do. You'll have to supply a callback as the second argument.

Vaccine answered 19/2, 2014 at 20:28 Comment(0)
T
2

In case you do not want to use promisify but do want SailsModel.query to return a promise.

/**
 * @param {Model} model - an instance of a sails model
 * @param {string} sql - a sql string
 * @param {*[]} values - used to interpolate the string's ?
 *
 * @returns {Promise} which resolves to the succesfully queried strings
 */
function query(model, sql, values) {
  values = values || [];

  return new Promise((resolve, reject) => {

    model.query(sql, values, (err, results) => {
      if (err) {
        return reject(err);
      }

      resolve(results);
    });
  });
}

// and use it like this
query(User, 'SELECT * FROM user WHERE id = ?', [1]).then(console.log);
Toggery answered 7/10, 2016 at 11:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.