subscribe: Posts | Comments

Creating callback functions or event handlers as Object methods in Javascript or node.js

0 comments

In event driven Javascript code – especially in node.js, we often need to create callback functions that are invoked on various events, such as completion of an IO operation on a file, database or network. Typically, such callback functions can be created as anonymous functions.

For example,

fs = require('fs');

fs.readFile('test.txt', 'ascii', function (err, data) {
    if (err) throw err;
    console.log(data);
});

The above code will output the contents of the file on console. For fun, assume we have a single word ‘there!’ in the file test.txt.

Now we want to implement readFile as an Object’s method. That requires a bit more code.

For example, suppose we define an Object MyClass with a method mymethod and an instance variable myvariable as follows

function MyClass(value) {
    this.myvariable=value;
}

MyClass.prototype.mymethod = function(data) {
    console.log(this.myvariable+' '+data);
}

We create an instance of this class using

var myobject = new MyClass('hello');
myobject.mymethod('there!');

This will show ‘hello there!’ on the console.

Now we define another method in MyClass – readFile, that reads a specified file, and on completion, calls mymethod

fs = require('fs');

MyClass.prototype.readFile = function(filename) {
    var self=this;
    fs.readFile(filename,'ascii',function(err,data) {
        self.mymethod.apply(self,[data]);
    });
}

Note that in the above method, we have used the magic Function.apply of Javascript inside the anonymous callback. This ensures that when mymethod is invoked, the ‘this’ automatic variable refers to the object instance. We test this by creating an instance of our object and then call its readFile method

var myobject= new MyClass('hello');
myobject.readFile('test.txt');

This will output ‘hello there!’ on the console. Simple.

Here is the entire example code…

var fs=require('fs');

function MyClass(value) {
    this.myvariable=value;
}

MyClass.prototype.mymethod = function(data) {
    console.log(this.myvariable+' '+data);
}

MyClass.prototype.readFile = function(filename) {
    var self=this;
    fs.readFile(filename,'ascii',function(err,data) {
        self.mymethod.apply(self,[data]);
    });
}

var myobject= new MyClass('hello');
myobject.readFile('test.txt');