dan_vitch
dan_vitch

Reputation: 4559

Add function to object

I have the following code

var PROMO = PROMO || {};

PROMO.Base = (function () {
  var _self = this;

  var Init = function () {
    WireEvents();
  };

  var WireEvents = function () {
   //wire up events
  };

} ());

In the same file I have the code to call the above function

I am trying to get to an end point where I can use the following code

 $(document).ready(function () {
    PROMO.Base.Init();
 });

this gives the error

Cannot call method 'Init' of undefined

Now I know there are many ways to write javascript, but in this case I want to be able to call my functions, or least the Init method in the way shown above.

Upvotes: 5

Views: 518

Answers (3)

flavian
flavian

Reputation: 28511

Working fiddle with both patterns, using IIFE and direct attribution.

Using var makes the definition private and your function is returning nothing. Use this:

PROMO.Base = {
    Init: function() {
    },
    WireEvents: function() {
    };
};

You are wrapping the definition with an IIFE(Immediately Executed Function Expression). So your PROMO.Base object will be assigned the value of that (function(){//blabla})(); returns. But your function doesn't have a return statement. By default it will return undefined.

Which is way your PROMO.Base will be undefined and you get this:

Cannot call method 'Init' of undefined

If you really want that IIFE:

var PROMO = PROMO || {};
// NEVER use _self = this inside static functions, it's very dangerous.
// Can also be very misleading, since the this object doesn't point to the same reference.
// It can be easily changed with Function.prototype.call and Function.prototype.apply
PROMO.Base = (function () {

    _PROMO = {
        Init : function () {
            document.body.innerHTML += "itworks";
        },
        WireEvents : function () {
   //wire up events
        }
    }
    return _PROMO;
} ());
PROMO.Base.Init();

Update

The better and easier pattern is to simply assign the functions to PROMO.Base. Dully note you should not capitalize static functions, but only constructors. So if something is not meant to be instantiated, don't call it Init, it should be init. That is the convention.

var PROMO = {};
PROMO.Base = {};
PROMO.Base.init = function() {
    console.log("this works");
};
PROMO.Base.wireEvents = function() {
    console.log("this is a static function too");
};

Upvotes: 5

Tim Vermaelen
Tim Vermaelen

Reputation: 7059

You can attach it to the window object like ...

window.PROMO = (function($, _){

// this will access PROMO.Base 
PROMO.Base = {
    // inner functions here
    Init:{}
};

})(jQuery, _);

Then load it as you do.

Or if you depend from jQuery

(function($){
    var PROMO = {
        // inner functions
        Init: function(){},
        WireEvents: function(){}
    };

    $.PROMO = PROMO;
})(jQuery);

On DOM ready

jQuery(function ($) {
    var promo = $.PROMO || undefined;
    promo.Base.Init();
});

Upvotes: 0

Drew
Drew

Reputation: 663

var PROMO = PROMO || {};

PROMO.Base = (function () {
  var _self = this;

  var Init = function () {
    WireEvents();
  };

  var WireEvents = function () {
   //wire up events
  };

  var reveal = {
        Init: Init        
  };

  return reveal;

} ());

You need to return the public facing functions. See updated code.

Upvotes: 6

Related Questions