Robin Heller
Robin Heller

Reputation: 420

NodeJS passing variable to already defined callback function

Consider the following code:

    if(connections.hasOwnProperty(id)){
        console.log('client '+id+' is connected. querying redis.');
        id = id;
        redisClientActor.lrange("NOTIFICATIONS_"+id, 0, 0, function(err, reply) {
            if(reply !== null && reply !== undefined){
                console.log(JSON.stringify(Object.keys(connections)));
                connections[id].sendUTF(reply);
                console.log('Forwarded notification to client '+id);
            }else{
                console.log(err);
            }
        });
    }else{
        console.log('Received notification, but client '+id+' not connected.')
    }

it's part of a very basic notification server written in NodeJS. It's using the redis npm package. Because of the asynchronous nature of Node I understand why the code is unable to work currently (id is out-of-scope which leads to sendUTF failing which leads to the script crashing).

If lrange was a self-defined function I'd simply add a third parameter here and be done with it. But since it isn't I struggle to find the solution as to how access "id" inside of the lrange callback (l5 and following)

I'd be very grateful for a quick hint in the right direction.

Upvotes: 1

Views: 143

Answers (1)

Tobias Gassmann
Tobias Gassmann

Reputation: 11819

In case you are iterating through a loop that alters the value of "id", the callbacks would all see the last value of "id" which was assigned to it during the last iteration.

In that case you need to capture the value of id with a closure:

var produceClosureForId = function(id){
    return function(err, reply) {
        if(reply !== null && reply !== undefined){
            console.log(JSON.stringify(Object.keys(connections)));
            connections[id].sendUTF(reply);
            console.log('Forwarded notification to client '+id);
        }else{
            console.log(err);
        }
    };
}
redisClientActor.lrange("NOTIFICATIONS_"+id, 0, 0, produceClosureForId(id) );

Upvotes: 1

Related Questions