0

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..

johhny B
  • 1,342
  • 1
  • 18
  • 37
  • 1
    What if you add `this.callback()` in your `close` function? Is it working? – raphv Jun 03 '16 at 15:13
  • callbacks are an antiquated way to deal with this problem - get in the habit of using [promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) – Jamiec Jun 03 '16 at 15:17
  • @Jamiec a promise is not the solution for events, since events may happen more then once. – Niels Steenbeek Jun 03 '16 at 15:22
  • @NielsSteenbeek Generally you can only close something once though! And from the q `insert a callback` - "a" is singular. – Jamiec Jun 03 '16 at 15:24
  • You need an emitter. When implemented you should be able to do m.on("close", function () {...}); – Niels Steenbeek Jun 03 '16 at 15:24
  • @Jamiec see http://stackoverflow.com/questions/23803743/what-is-the-explicit-promise-construction-antipattern-and-how-do-i-avoid-it and have a close look to the qouting Esailija. – Niels Steenbeek Jun 03 '16 at 15:26
  • Hi Barmar it's not an answer because it doesn't work... – johhny B Jun 03 '16 at 15:34

1 Answers1

2

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
user3297291
  • 22,592
  • 4
  • 29
  • 45
  • Where in the question does it say that he needs multiple callbacks? – Barmar Jun 03 '16 at 15:20
  • @Barmar: nowhere. I'm sorry. I've added "(or just one)", but I think naming a method `addCallback` suggests there can be more, while if it would've be named `setCallback` I'd expect only one. – user3297291 Jun 03 '16 at 15:21