1

I am writing javascript code with revealing prototype pattern for the first time. I am having problems. When I call add function when user clicks add button then it shows me this error in the console.

Uncaught TypeError: Cannot call method 'add' of undefined

How can I solve this problem?

here is my script.js code

$(function () {
var todo = Todo('contents');
$('.addBtn').on('click', function() {
 var name = $(this).parent().find('input[type="text"]').val();
 todo.add(name);
});
$('.contents').on('click', '.remove', function() {
 var el = $(this).parent();
 todo.remove(el);
});
$('.contents').on('click', '.update', function() {
 var dom = $(this);
 todo.addUpdateField(dom);
});
$('.contents').on('click', '.updateBtn', function() {
 var el = $(this);
 todo.update(el);
});
});

here is my todo.js code

var Todo = function(c) {
 this.contents = $('.' + c);
};
Todo.prototype = function() {
var showel = function (d) {
 this.contents.prepend(d);
},
add = function (name) {
 if(name != "") {
 var div = $('<div class="names"></div>')
 .append('<span>' + name + '</span>')
 .append("<button class='update' class='update'>Edit</button>")
 .append("<button class='remove' name='remove'>Remove</button>");
 }
 return showel(div);
},
addUpdateField = function (dom) {
 var name = dom.parent().find('span').text(),
 field = $('<input type="text" value="' + name + '" />'),
 update = $('<button class="updateBtn">Update</button>');
 dom.parent().html('').append(field).append(update);
 return;
},
update = function(el) {
 var val = el.parent().find('input').val();
 el.parent().html('<span>' + val + '</span>')
 .append('<button class="update" class="update">Edit</button>')
 .append('<button class="remove" class="remove">Remove</button>');
 return;
},
remove = function (el) {
 return el.remove();
};
return {
 add : add,
 update : update,
 remove : remove,
 addUpdateField : addUpdateField
};
}();

Update

After changing var todo = Todo('contents');

to

var todo = new Todo('contents');

I get this error

Object [object Object] has no method 'add'

update 2

here is my on jsfiddle

asked Aug 8, 2012 at 12:44

2 Answers 2

3

You're not properly constructing your object, so it does not have any of the prototypes:

var todo = Todo('contents');

should be:

var todo = new Todo('contents');

Here is an SO question explaining what is happening when you forget the new.

Edit: the way you are defining your prototype functions is messing up the context (what this points to). Try a pattern like this instead:

Todo.prototype = {
 method1: function () { ... },
 method2: function () { ... }
};

fixed fiddle: http://jsfiddle.net/BagmY/3/

answered Aug 8, 2012 at 12:46
Sign up to request clarification or add additional context in comments.

5 Comments

Now it shows this error Object [object Object] has no method 'add'
Could you tell me why am I getting above error i.e. this one Object [object Object] has no method 'add'
@al0neevenings i honestly don't know why it wouldnt work after adding the new, the code you posted should work. perhaps another member will be able to spot the problem.
I have added jsfiddle link. could you please modify my code to make it work? thanks
I am using revealing prototype pattern to learn this pattern. The example you posted is a modular pattern. Secondly it does work now but when I use return showel(div) line in add method then it shows this error Cannot call method 'append' of undefined . And when I use this line in add method return this.contents.prepend(div); then it works. Why am I getting this error when I do it the first way and how can I make it work while sticking to revealing prototype pattern?
1

You're trying to assign Todo's prototype to a self-calling function. However, the prototype is just getting assigned to a function and not the expected return object.

Here's your working fiddle. I assigned the prototype directly to an object with your methods.

Also, JS parses from top to bottom. Therefore, define your new instance of Todo after you declare what Todo is.

This is what a self-calling function should look like:

Todo.prototype = (function() {
 // ...
 return {
 add: add,
 update: update,
 remove: remove,
 addUpdateField: addUpdateField
 };
})();​
answered Aug 8, 2012 at 13:02

3 Comments

could you elaborate your answer please?
I am using revealing prototype pattern to learn this pattern. The example you posted is a modular pattern. Secondly it does work now but when I use return showel(div) line in add method then it shows this error Cannot call method 'append' of undefined . And when I use this line in add method return this.contents.prepend(div); then it works. Why am I getting this error when I do it the first way and how can I make it work while sticking to revealing prototype pattern?
The fiddle doesn't use any specific pattern. The example above is the revealing module pattern. I'm not sure what your problem is--try recreating it in a fiddle.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.