1

I am creating a js library that handle item operations from collection object directly as follow. I want to allow to add dynamic user defined object function for each item and make these function available through collection object directly with index (please see example implementation).

var item = function (obj) {
    this.foo = function () {
        alert("foo" + this.name);
    }
    for (var i in obj) {
        this[i] = obj[i]; //dynamic fields (overridable)
    }
}
var collection = function (list) {
    var self=this;
    this.items = [];
    if (list && list.length > 0) {
        for (var i in list) {
            var t = new item(list[i]); // create new item            
            for (var j in t) {
                if (typeof (t[j]) === "function") {
                    this[j]=function(index,arg1,arg2,arg3){                        
                        self.items[index][j](arg1,arg2,arg3); //not working (unreliable)
                        console.log(j) //undefined
                        // problem is here j cannot be visible from function handler.
                        //I need to call dynamic j function within handler
                    }
                }
                this.items.push(t); //push each item into collection
            }
        }
    }
}
var obj=new collection([
    {
        id:1,name:"apple",
        bar:function(arg){
            alert(arg+" "+this.name);
        }
    }
    ]);
    obj.foo(0); //equivalent to obj.items[0].foo();
    obj.bar(0,"parameter"); //equivalent to obj.items[0].bar("parameter");

As described in comments in above code snippet, I can't call item's function from collection function dynamically. How can I achieve this purpose. Please help me.

5
  • FUNCTION.name will get the function name, is that what you want? Commented Apr 27, 2015 at 4:43
  • Thanks, But function assigned to (dynamic) field is anonymous. what I want is to retrieve is field name. Commented Apr 27, 2015 at 4:59
  • I created a jsfiddle of your code, and it works without any changes. jsfiddle.net/avivshaked/o6g9k8s6 Commented Apr 27, 2015 at 5:05
  • @user1147987, I tried your code on fiddle and it works perfectly, I didn't get your problem can you have a look at "jsfiddle.net/w8npva2b"? Commented Apr 27, 2015 at 5:06
  • Yes it working for one item,but It's not working if there are more than one item in collection. Commented Apr 27, 2015 at 5:36

1 Answer 1

1

You cannot get related field name from scope of handler. What you need to do is to create new function object with field name, i.e. function name= field name. To do so, you have to do a little trick in specifying dynamic function of item to collection object. Within handler scope, you can cast function name via arguments.callee
Change this snippet

var t = new item(list[i]); // create new item            
        for (var j in t) {
            if (typeof (t[j]) === "function") {
                this[j]=function(index,arg1,arg2,arg3){                        
                    self.items[index][j](arg1,arg2,arg3); //not working (unreliable)
                    console.log(j) //undefined
                    // problem is here j cannot be visible from function handler.
                    //I need to call dynamic j function within handler
                }
            }
            this.items.push(t); //push each item into collection
        }

in to this:

this.items.push(new item(list[i]));    
        var t=this.items[this.items.length-1];
        for (var j in t) {
           if (typeof (t[j]) === "function") {
                this[j]=new Function( "return function " + j + "(idx,arg1,arg2,arg3){console.log(this.items[idx]);var fn = arguments.callee.toString().substr('function '.length);fn = fn.substr(0, fn.indexOf('(')); if(this.items[idx][fn])this.items[idx][fn](arg1,arg2,arg3);}")();                    
            }
          //  this.items.push(t); //push each item into collection
        }                    
                }

jsfiddle sample : http://jsfiddle.net/kyawlay/7528t7z8/1/

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks alot. it's incredable. But when I add new item to collection it call first object what's the error as follow var obj=new collection([ { id:1,name:"apple", bar:function(arg){ alert(arg+" "+this.name); } },{ id:2,name:"orange", bar:function(arg){ alert("bar1 "+arg+" "+this.name); } } ]); obj.foo(1); //equivalent to obj.items[0].foo(); obj.bar(1,"parameter"); //equivalent to obj.items[0].bar("parameter");
It's because of your focus of assigning item to collection. I update answer please try that approach. jsfiddle sample : jsfiddle.net/kyawlay/7528t7z8/1

Your Answer

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.