0

I’m using Q promises with NodeJS and my code is not working as expected.

I have an array of type ObjA. Each ObjA has a property, objB, of type ObjB. ObjB has an async method called extract that does an async task and sets / updates objB properties. I use Q.defer in the async function and return the deferred promise.

I add the deferred promise to an array and call Q.all. This part works as expected and objB.exract is called (I have verified via console.log).

But when I subsequently output the results, objB properties haven't changed (even though I set them in extract).

Here is the code:

//file ObjA.js

exports.ObjA = function(data)
{
this._id = data.id;
this._created_at = data.created_at;
this._objB = new ObjB.ObjB(data.somefield);
};

//file ObjB.js

exports.ObjB = function(data)
{
    this._afield = data;
    this._bfield = '';
    this._cfield = '';
};

exports.ObjB.prototype.extract = function()
{
    var deferred = Q.defer();
    async_call(this._afield, function(e, resp)
    {
        if (e)
        {
            console.log(e);
            return deferred.reject(e);
        }
        else
        {
            this._bfield = resp.val1;
            this._cfield = resp.val2;
            console.log(this._bfield + ", " + this._cfield);
            return deferred.resolve(resp);
        }
     };
    return deferred.promise;
};

//main file,

var alist = [];
// code to populate alist with objects of type ObjA
var queue = [];
for (var i=0; i<alist.length; i++)
{
    queue.push(alist[i]._objB.extract());
}

Q.all(queue).then(function(succ)
    {
        console.log('final values');
        console.log(alist);
    },
      function(err)
    {
        console.log(err)
    }
    );

When I run this, extract is correctly called and this._bfield and this._cfield are correctly output from the console.log. But then it comes to the success function for Q.all() and it prints 'final values', followed by '' for objB._bfield and objB._cfield.

Why are the values set in extract not being printed? I'm guessing this has something to do with object references but can't pinpoint what is wrong here.

Any help would be much much appreciated.

thanks

1 Answers1

0

be care of 'this' keyword, replace this piece of code :

async_call(this._afield, function(e, resp)
{
    if (e)
    {
        console.log(e);
        return deferred.reject(e);
    }
    else
    {
        this._bfield = resp.val1;
        this._cfield = resp.val2;
        console.log(this._bfield + ", " + this._cfield);
        return deferred.resolve(resp);
    }
 };

to:

var that = this;
async_call(this._afield, function(e, resp){
    if (e)
    {
        console.log(e);
        deferred.reject(e);
    }
    else
    {
        that._bfield = resp.val1;
        that._cfield = resp.val2;
        console.log(that._bfield + ", " + that._cfield);
        deferred.resolve(resp);
    }
 });
C.C.
  • 1,060
  • 3
  • 13
  • 25