1

I'm trying to implement module pattern from an acticle from css-tricks Here is my return object:

var MyModule = (function() {
  var pSettings; //private context

  return {
      settings: {
          time: Date.now(),
          myBtn: document.getElementById('myBtn')
      },

      init: function () {
          pSettings = this.settings;
          this.bindUIActions();
      },

      bindUIActions: function () {
          pSettings.myBtn.onclick = someFunction;
          console.log('binding');
      },

      someFunction: function() {
          console.log('someFunction');
      }
  }
})();

Fiddle

When I use MyModule.init(), I have an error like myBtn is null

Uncaught TypeError: Cannot set property 'onclick' of null

, why is it happends?

uladzimir
  • 5,469
  • 5
  • 28
  • 48

1 Answers1

3

It's probably about timing. document.getElementById('myBtn') is being executed when my Module is first defined which is probably before your HTML document has been parsed and thus myBtn doesn't yet exist.

Your object inside ofMyModule and all of its properties are being created at the time that MyModule is first defined and created. The myBtn property is a static value, initialized when the property is first created. If you want it to be a function that is evaluated only upon demand, then you must make it a function that you can call at the desired time.

You have several ways you can fix it.

  1. You can stop trying to pre-fetch the myBtn DOM element and just fetch it upon demand only when needed.

  2. You can move this javascript to the end of the <body> tag or put it in some sort of ready function so it won't execute until the DOM is ready.

  3. You can cache myBtn upon first use (when the DOM is ready) rather than in advance.

  4. You can change the initialization of the myBtn property to be in the .init() method when the DOM is ready.

My suggestion would be the first option.

jfriend00
  • 580,699
  • 78
  • 809
  • 825
  • @baxxabit - Please read what I wrote again. I'm trying to explain to you that you are initializing the `settings.myBtn` property too early before the 'myBtn' element exists. – jfriend00 Feb 26 '14 at 08:03
  • I have wrote comment before you update answer, thanks! – uladzimir Feb 26 '14 at 08:04
  • I use angularjs template, so this is a problem, why myBtn property is null in module. Thanks for explaination. Module loaded before template – uladzimir Feb 26 '14 at 08:07
  • @baxxabit - You can also just initialize `myBtn` in the `.init()` method rather than in the initial definition when the DOM is ready. – jfriend00 Feb 26 '14 at 08:09