Search code examples
javascriptnode.jssocketseventemitter

Node.JS Event Emitter - Call On Method Internally


I am writing a program for my beaglebone black to control certain aspects of beer brewing process via a webpage. I am using socket.io to keep communications real-time. To do this, I am passing the socket object to actions located in the hardware classes. Some of the classes, such as my temp_sensor class use the eventEmitter pattern to allow other objects to subscribe to its data. However, when I use method of the temp_sensor to subscribe a passed in socket, it is telling me that the object (this) does not have a method "on". Below is my code:

module.exports = temp_sensor;

var fs = require("fs"),
    exec = require("child_process").exec,
util = require("util"),
EventEmitter = require("events").EventEmitter;

var w1path = "/sys/bus/w1/devices/";


function temp_sensor(config){
// Put sensor verification code here//
this.name = config.name;
this.address = config.w1_address;
this.path = w1path + this.address + "/w1_slave";
this.value = null;
this.unit = config.unit;
this.emit_interval = 2000;
this.type = config.type;
this.subscribers = 0;
this.emitting = false;
this.prev_temp = null;
if (config.emit_interval){this.emit_interval = config.emit_interval;}
var self = this;
/*this.emit_data = setInterval(self.readSensor(function(temp) {
    if (temp !== this.prev_temp) {
        var timestamp = new Date().toJSON()
        var data = {
            "name": this.name,
            "temp":temp,
            "timestamp": timestamp
        };
        self.emit("temp_data", data);
        this.prev_temp = temp;
    };
}),this.emit_interval);*/
}

util.inherits(temp_sensor, EventEmitter);

temp_sensor.prototype.readSensor = function(callback){
var cmd = "cat " + this.path + " | grep t= | cut -f2 -d= | awk '{print $1/1000}'";
exec(cmd , function( error, stdout, stderr ) {
    if (error) { callback(error); }
    callback( Math.round((parseFloat(stdout) * 1.8 + 32) * 10) / 10 );
});
};



// component actions
temp_sensor.prototype.actions = [];

temp_sensor.prototype.actions["subscribe"] = function(socket) {
this.subscribers++;
this.on("temp_data",function(data) {
    socket.emit("temp_sensor",data);
});
};

temp_sensor.prototype.actions["unsubscribe"] = function(socket) {
this.subscribers--;
// remove listener
};

I am getting this error:

/var/lib/cloud9/brewbone/lib/temp_sensor.js:64 this.on("temp_data",function(data) { ^ TypeError: Object has no method 'on' at Array.temp_sensor.actions.subscribe (/var/lib/cloud9/brewbone/lib/temp_sensor.js:64:7)

Any help would be greatly appreciated!


Solution

  • What you are doing is that you inherit EventEmitter in *temp_sensor*. And the method on is actually available in the prototype of *temp_sensor*. But later you create another object which has its own prototype - actions["subscribe"]. So, the this here:

    temp_sensor.prototype.actions["subscribe"] = function(socket) {
       this.subscribers++;
       this.on("temp_data",function(data) {
          socket.emit("temp_sensor",data);
       });
    };
    

    points to something else.

    I'll suggest to leave the prototype and try implementing the revealing module pattern.