3

I am trying to pass a reference to a jQuery Object to a module and have been getting an error that says: Uncaught TypeError: undefined is not a function

I am working on a fiddle to try and understand this pattern that I saw, as well as to understand prototype and the new keyword.

I am not sure what is causing this error. Here's my HTML and JavaScript along with a fiddle.

Fiddle.

HTML:

<div class="js-container" data-options="true"></div>
<div class="js-container" data-options="false"></div>

JavaScript:

$('.js-container').each(function (i, element) {
    new MyClass($(element));
    console.log($(element));
});
var MyClass = (function ($element) {
    this.$element;
    console.log(this.$element);    
    this.init();    
    MyClass.prototype.init = function () {
        this.addText();        
        return this;
    };    
    MyClass.prototype.addText = function () {
        var optText = this.$element.attr('data-options');
        this.$element.text(optText);        
        return this;
    };    
}());

I am trying to learn to write more module with JavaScript. So please let me know if I have anything else that is incorrect. Thanks!

Aruna
  • 11,441
  • 3
  • 24
  • 39
Mdd
  • 3,240
  • 9
  • 38
  • 65
  • 1
    The function that has `$element` as argument is immediately executed, but you're not passing any arguments. And `this.$element` doesn't exist, thus `undefined`. You're mixing things up... – elclanrs Jan 23 '14 at 02:02
  • 1
    See here http://stackoverflow.com/questions/8228281/what-is-this-iife-construct-in-javascript, and here http://stackoverflow.com/questions/3127429/javascript-this-keyword – elclanrs Jan 23 '14 at 02:03
  • 1
    Hint: What is the value of `MyClass`? (The value is the result of *invoking* the anonymous function - note the `()` near the end.) – user2864740 Jan 23 '14 at 02:05
  • THanks elclanrs and user2864740. I was thinking that it was because I was not passing any reference to the () near the end. But I was also thinking that invoking new MyClass($(element)) would pass the jQuery selector to MyClass. How would you pass the element to MyClass? The new keyword is something new that I'm trying to understand. – Mdd Jan 23 '14 at 02:10
  • I editted my question to better explain what I'm trying to learn. I saw a pattern similar to what I posted and was trying to understand a few concepts that I've read about but have not practiced much. Such as the new keyword and prototype. – Mdd Jan 23 '14 at 02:23

3 Answers3

2

You are defining MyClass after you run the code that uses MyClass. Also, stuffing your class into a variable rather than declaring it the "traditional" way causes some problems. Try this:

function MyClass ($element) {

  this.$element;
  console.log(this.$element);

  // more code...
}

$('.js-container').each(function (i, element) {
  new MyClass($(element));
  console.log($(element));
});

Also, move your MyClass.prototype. definitions out of the actual MyClass. Put them after.

rvighne
  • 17,348
  • 7
  • 45
  • 64
  • Thanks! I editted my question to better explain what I'm trying to do. I've read about prototype and the new keyword but have not used them before. So I am trying to pass in an element to the module and see if I what I can do from there. :) – Mdd Jan 23 '14 at 02:25
  • @Mdd Edited to fix that, but it's not considered good to change the question so much after asking it. – rvighne Jan 23 '14 at 02:28
  • @rvignhne Thank you and I'm sorry about edditing the question. Thank you for the example. How would you extend MyClass to add another method with prototype though? – Mdd Jan 23 '14 at 02:40
  • 1
    @Mdd Again... something for another question... but fine. Type something like `MyClass.prototype.method = function () {}` AFTER MyClass has been declared. – rvighne Jan 23 '14 at 02:55
  • Thank you! That's what I was trying to figure out. I've been reading about prototype and modules but was trying to actually see if I could make one. – Mdd Jan 23 '14 at 02:57
1

For what it is worth, a lot of the time when I see this problem I find that I have inadvertently called a function before it was referenced in the html. For example, I just called a jquery method in a js file before I loaded my jquery files. Putting the jquery references further up on the page solved it.

RandyWhirl
  • 93
  • 9
1

None of the above answers worked for me. But of course, my problem was special. I was recycling an old project to make a new one and there was a method that made the class that I had forgotten about (and was passing in a string instead of a function), and the fact that it wasn't updated was giving me this error, even though I had the syntax elsewhere all correct.

Moral: if you try the above solutions and it still doesn't work, desk check and make sure everyplace where the surrounding method is called passes in the right parameters.

shieldgenerator7
  • 1,037
  • 11
  • 20