Rash
Rash

Reputation: 8217

redis event handler function is losing class reference

In my NODEJS application I am subscribing to different redis events. For all events, I want to call my router which has the logic to route the request based on nature of events. As you can see in my redis.js file, I am registering a function to the receive those events.

redisSubscriber.on('pmessage', test.route) <-- Function is an instance of class Test

I am using node-redis. When node-redis calls my route() method, it is loosing its object reference i.e. it is not able to access this. To illustrate this, I am trying to access this.message from the route() method which has been called by node-redis on receiving an event.

File - test.js

class Test {
  constructor () {
    this.message = 'hello'
  }

  route (pattern, channel, message) {
    console.log(this.message) // Output: undefined
    console.log(pattern + ' ' + channel + ' ' + message) // Output: __keyevent@*__:set __keyevent@0__:set key
  }
}

module.exports = Test

File - redis.js

const Redis = require('redis')

let redis = Redis.createClient({
  host: 'localhost',
  port: 6379
})
let redisSubscriber = redis.duplicate()

let Test = require('./test')
let test = new Test()

redisSubscriber.on('pmessage', test.route)
redisSubscriber.psubscribe('__keyevent@*__:set')
redisSubscriber.psubscribe('__keyevent@*__:del')
redisSubscriber.psubscribe('__keyevent@*__:expired')

// Allow redis-subscriber to subscribe to all events.
setTimeout(function () {
  // When I set this key, a set event is generated.
  redis.set('key', 'value', function (error) {
    if (error) throw error

    // Allow set event to propagate, then quit redis.
    setTimeout(function () {
      redisSubscriber.unsubscribe()
      redisSubscriber.quit()
      redis.quit()
    }, 100)
  })
}, 100)

Upvotes: 0

Views: 253

Answers (1)

mayank
mayank

Reputation: 543

try to use a wrapper function over your test.route as redis callback function uses global scope, and this will not be available in the callback.

Replace this

redisSubscriber.on('pmessage', test.route)

with

redisSubscriber.on('pmessage',(pattern, channel, message) => {
   test.route(pattern, channel, message);
})

Upvotes: 1

Related Questions