TypeError: Cannot call method 'then' of undefined

1.5k views Asked by At

I have the following code executing inside a controller in Sailsjs. The underlying adapter is sails-orientdb. I get the following error back

TypeError: Cannot call method 'then' of undefined

Why is this error occurring?

        User.query("select id from User where username='" + req.param("userid") + "'").then(function(userData){
        console.log(userData);
        return userData;
    }).fail(function (err) {
        console.log("Handled");
    });
2

There are 2 answers

2
Dário On BEST ANSWER

To expand on what @jaumard said.

Background

Usually it's recommend to use the standard waterline query methods such as find(), update(), create(), destroy(), etc. These methods support callbacks and promises and these methods will work the same way against any waterline adapter (OrientDB, MySQL, MongoDB, etc).

Sometimes you may want to do something more complex which is not supported by the standard waterline methods and for that sails-orientdb extends the waterline definition with query(), among other methods.

sails-orientdb .query()

sails-orientdb query uses callback so you can use it like this:

  // Assume a model named "Friend"
  Friend.query("SELECT FROM friendTable WHERE name='friend query'", function(err, retrievedUsers){
    console.log(retrievedUsers);
  });

UPDATE: since v0.10.53 the below is also supported:

Friend.query("SELECT FROM friendTable WHERE name='friend query'")
.then(function(retrievedUsers){
  console.log(retrievedUsers);
});

If you really want to use the promise mechanism you have 2 options:

promisify query()

By using bluebird promise's promisify. Example:

var queryPromise = Promise.promisify(User.query);
queryPromise('select...').then(function(){/*...*/})

Use getDB()

Another option is to use sails-orientdb custom method getDB. This method returns an Oriento db instance which can be used for promisified queries. Example:

User.getDB().query('select from OUser where name=:name', {
  params: {
    name: 'Radu'
  },
  limit: 1
}).then(function (results){
  console.log(results);
});
2
jaumard On

I don't think promise works with .query method (maybe I'm wrong). You can use this instead :

User.findOne()
.where({ username: req.param("userid") })
.then(function(user){
    return user;
}).then(function(user){
    //Do what you want 
}).catch(function(err){
    // An error occurred
});

With sails and waterline it's not recommended to use .query when you not really need to.

See this tutorial it may help : http://documentup.com/kriskowal/q/#tutorial/chaining