Search code examples
javascriptnode.jspromiseloopback

Loopback APIs and promises


In the loopback documentation, it says "The following built-in models support the promises API: User Application PersistedModel"

So if in a unit test, I want to create a user, then log that user in, then how come using the callback method works:

aUser.create({email: 'user3@bar.com', password: 'foo'}, function() {
                aUser.login({email: 'user3@bar.com', password: 'foo'}, 'user', function (err, res) {
                    // stuff
                });
            });

but using promises doesn't:

var Promise = require ('bluebird');
aUser.create({email: 'foo@bar.com', password: 'bar'})
                .then(function(err, res){
                    aUser.login({email: 'foo@bar.com', password: 'bar'}, 'user');
                })
                .then(function(err, res) {
                    //stuff
                })
                .catch(function(err){
                    console.error(err);
                });

I've also tried Promise.join, Promise.mapSeries.


Solution

  • Two issues:

    1. Your promises code doesn't do the same thing as your non-promises code. In your non-promises code, you don't do "stuff" until aUser.login completes successfully, but in your promises code you're not waiting for that. To do the same thing, your first then callback needs to return the promise that aUser.login returns. Otherwise, the promise your first call to then returns is resolved with the value undefined, rather than settling based on the resolution or rejection of the aUser.login promise.

    2. The arguments you're declaring for your then callbacks are incorrect: The resolution callback receives a single argument, which is the resolved value. It's not like a NodeJS callback that receives two.

    So (see lines tagged with ***):

    var Promise = require ('bluebird');
    aUser.create({email: 'foo@bar.com', password: 'bar'})
        .then(function(res){                                                     // ***
            return aUser.login({email: 'foo@bar.com', password: 'bar'}, 'user'); // ***
        })
        .then(function(res){                                                     // ***
            //stuff
        })
        .catch(function(err){
            console.error(err);
        });
    

    Side note: If you're not using Promise in your code, no need to require it.