xenophon xenophon - 6 months ago 16
Javascript Question

What's the best way to add a callback to the following module?

I have the following module

var m=(function() {
// setup variables

return {
center: function() {
// do stuff
},

open: function(settings) {

// do open stuff
// setups the handler for the close...

$close.on("click",function(e) {
e.preventDefault();
m.close();
});
},

close: function() {
// do close stuff
// ** need to add code here
//to perform a callback function on close

// EDIT
if(this.hasOwnProperty("callback"))
callback();
},

//** EDITED
addCallback: function(func) {
this.callback=func;
}

};
}());

// open
m.open();


The close in the triggered automatically by a click event. I want to somehow insert a callback into the close() to be performed at the time of closing... I thought about adding a function like

addCallback(callback) {
this.callback=callback;
}


but i'm not sure how to call that within the close().

** EDIT **

Thanks to user3297291 for the below response and Barmar you were right I do actually only need one callback not an array. I have edited the above code by adding a addCallback(). Then the code to run would be:

m.open()
function check() {
alert("hello");
}

m.addCallback(check);


But this doesn't work I'm trying to understand why and I new to javascript OO..

Answer

You'll have to keep track of an array of callbacks (or just one). The simplest implementation could be something like this:

var m = (function() {

  var onCloseCallbacks = [];

  return {
    addOnCloseCallback: function(cb) {
      onCloseCallbacks.push(cb);
    },
      
    close: function() {
      console.log("Closing");
      onCloseCallbacks.forEach(function(cb) {
        cb();
      });
    }
  };
}());


m.addOnCloseCallback(function() {
  console.log("After close");  
});

m.close();

Note that the array of callbacks is defined inside the closure.

For a more advanced solution, you'd want to be able to dispose the callback from outside of the m module. Here's an example of how this could be added:

var m = (function() {

  var onCloseCallbacks = [];

  return {
    addOnCloseCallback: function(cb) {
      onCloseCallbacks.push(cb);

      return {
        dispose: function() {
          var i = onCloseCallbacks.indexOf(cb);
          
          onCloseCallbacks = onCloseCallbacks
            .slice(0, i)
            .concat(onCloseCallbacks.slice(i + 1));
        }
      };

    },

    close: function() {
      console.log("Closing");
      onCloseCallbacks.forEach(function(cb) {
        cb();
      });
    }
  };
}());


var myCallback = m.addOnCloseCallback(function() {
  console.log("After close");
});

m.close(); // Does trigger cb

myCallback.dispose();

m.close(); // Doesn't trigger cb