Sadaf Sid
Sadaf Sid

Reputation: 1570

calling chain method in javascript

I am using the following code but it is constantly giving me errors :

TypeError: container("accounts").atPosition("#left-top") is undefined

the code is :

function container(name, position) {
    return {
        pos: null,
        atPosition: function(position) {

            $(position).html(this.newContainer());
            //$(position+" .main").html("yes");
            this.pos = position;
        },
        populateData: function(rdata) {
            $("#left-top .main").html(rdata);
        },
        newContainer: function() {
            //alert(this.pos);
            return '<h3>' + name.toTitleCase() + '</h3>\
                <div class="main">\
                </div>';
        }
    };
}

container('accounts').atPosition('#left-top').populateData("yahoo!!!!");​

Why am I receiving this error and how can I fix it?

Upvotes: 1

Views: 879

Answers (4)

watashiSHUN
watashiSHUN

Reputation: 10484

function chaining is not a special javascript syntax, if you want, you can implement it in Java, Python or anything that supports OOP.

a.functionX().functionY() works because functionX() returns again an object which has a method called functionY()

in your case, functionX() should return the same object it is invoked on, therefore return this; will fix your problem

But this is not the end of the story!!!

@Rich S mentioned in his answer:

In order to make chaining work, you need to "return this;" at the end of any functions you want to chain.

which is not necessary true, chaining will work as long as you return an object(or any object), here is an example:

var str ="abc";
var strFromChain = str.replace('a','x').toUpperCase();
// use function chainning
document.write(strFromChain+'\n');
// result should be XBC

var str1 = "abc";
str1.replace('a','x');
var str1NotFromChain = str1.toUpperCase();
// if replace() returned this, str1NotFromChain should also be XBC
document.write(str1NotFromChain)
// but is it???????

Obviously replace() method of str did not return this instead it returned a new string with a different value, and this is easy to understand since strings are immutables, no matter what methods you call on str, its value will always be "abc".

I am just making a point here, it's not necessary for chaining method to return this, it can return a new object if it wants to. Even though online tutorials teach you to use this when implementing chaining functions (ie javascript.issexy) you should always pay attention to what is being returned when using a third party library(ie route chainning in expressjs)

Upvotes: 1

Anoop
Anoop

Reputation: 23208

You supposed to return this from functions for chaining. By default function return undefined (if you dont use new operator) . by returning this from function which don't have any thing to return will help in chaining.

function container(name, position) {
    return {
        pos: null,
        atPosition: function(position) {
            $(position).html(this.newContainer());
            //$(position+" .main").html("yes");
            this.pos = position;

            return this;
        },
        populateData: function(rdata) {
            $("#left-top .main").html(rdata);
            return this;
        },
        newContainer: function() {
            //alert(this.pos);
            return '<h3>' + name.toTitleCase() + '</h3>\
                <div class="main">\
                </div>';
        }
    };
}​

Upvotes: 7

Rich S
Rich S

Reputation: 418

Chaining doesn't happen automatically.

In order to make chaining work, you need to "return this;" at the end of any functions you want to chain.

In reality, all you're doing is calling the function on whatever you return. If you do "return this;" then you end up with a nice chaining syntax that affects the same object.

The jQuery developer guide is a good place to get quality JavaScript tips from, given your question, I'd recommend looking at http://docs.jquery.com/Plugins/Authoring#Maintaining_Chainability

Upvotes: 0

Quentin
Quentin

Reputation: 943510

The function you assign to atPosition doesn't have a return statement.

So when you call atPosition('#left-top'), you get the default return value of undefined

You need to return the object you wish to call populateData on (which should be this)

Upvotes: 2

Related Questions