0

Possible Duplicate:
javascript object, access variable property name?

I'm trying to call a method of an object by its name when certain event happens - here's my code:

var imageObject = {
    sendImage : function(obj) {
        "use strict";
        var thisId = obj.attr('id');
        var thisSubmit = obj.attr('data-submit');
        var thisCallback = obj.attr('data-callback');
        var thisUrl = $('#' + obj.attr('data-url')).text();
        new AjaxUpload(thisId, {
            action: thisUrl,
            name: 'thisfile',
            onSubmit: imageObject.thisSubmit,
            onComplete: imageObject.thisCallback
        });
    }
}

I would also like to pass the parameters to the submit and callback method.

At the moment nothing happens and I'm sure I'm not calling it right - could anyone explain how to achieve this?

I've also used the following for submit and complete :

onSubmit: function(file, extension) {
    imageObject.thisSubmit(file, extension);
},
onComplete: function(file, response) {
    imageObject.thisCallback(file, response);
}

But what I get is the error saying :

imageObject.thisSubmit is not a function

The attributes only store the name (string) of the method within the object - so it would be for instance 'uploadImage'.

Community
  • 1
  • 1
Spencer Mark
  • 5,263
  • 9
  • 29
  • 58

4 Answers4

3

TJ's answer is nearly there, except that (per the new code in your question) you need to either copy the arguments from onSubmit to thisSubmit, or use .apply() to copy them for you.

The code below uses the latter method, which avoids having to duplicate the function signature over and over:

new AjaxUpload(thisId, {
    action: thisUrl,
    name: 'thisfile',
    onSubmit: function() {
        imageObject[thisSubmit].apply(imageObject, arguments);
    },
    onComplete: function() {
        imageObject[thisCallback].apply(imageObject, arguments);
    }
});
Alnitak
  • 334,560
  • 70
  • 407
  • 495
  • What I did was simply this : onSubmit: function(file, extension) { imageObject[thisSubmit](file, extension); }, onComplete: function(file, response) { imageObject[thisCallback](file, response); } – Spencer Mark Jun 25 '12 at 13:02
  • @SpencerMark yeah, that works, but is what I meant about having to duplicate the function signature. The `.apply()` method makes the new code completely agnostic to the function signature - it simply never appears in the code. – Alnitak Jun 25 '12 at 13:03
  • @Alnitak - +1, well done for working out what the question is actually asking! – James Allardice Jun 25 '12 at 13:04
  • @SpencerMark - I think this should be the accepted answer. If you accept this instead of mine I'll delete my post. – James Allardice Jun 25 '12 at 13:05
  • @JamesAllardice believe me, it wasn't easy! ;-) No need to delete your answer, though! – Alnitak Jun 25 '12 at 13:05
  • I tried the .apply() approach, however I'm getting the error saying: 'file is not defined' - where 'file' is one of the arguments. – Spencer Mark Jun 25 '12 at 13:07
  • @SpencerMark that would imply a problem in the `AjaxUpload` function, then. Or maybe that we need to set `this` (the first parameter to `.apply`) to be the `imageObject` - I'll edit to show how. – Alnitak Jun 25 '12 at 13:08
  • It might be the problem with the AjaxUpload - it's the external script, but it seem to work when I pass the arguments through the function() and then onto the called method without the use of .apply() - I will accept this answer although it does not resolve my problem. – Spencer Mark Jun 25 '12 at 13:12
  • @SpencerMark curious - the only fundamentally different thing that `.apply()` does is setting the `this` context. I'd like to try and figure out why it didn't work exactly as written (although the edited version may work better) but there's not enough code shown to do that. – Alnitak Jun 25 '12 at 13:14
  • Thanks Alnitak - I've tried : onSubmit: function() { imageObject[thisSubmit].apply(imageObject, file, extension); }, onComplete: function() { imageObject[thisCallback].apply(imageObject, file, response); }, but I'm getting the same error. Just to clarify - all arguments should just be separated by coma - they don't need to be inside of array etc? – Spencer Mark Jun 25 '12 at 13:15
  • @SpencerMark no, you should write it **exactly** the way I did - `arguments` is a special pseudo-array containing the arguments that were passed to the function. You weren't supposed to replace it with your actual argument list! – Alnitak Jun 25 '12 at 13:17
  • Sorry Alnitak - I misinterpreted this bit - it works fine now with the keyword 'arguments'. Many thanks! – Spencer Mark Jun 25 '12 at 13:19
2

If I've understood your question correctly, you need to use the square bracket syntax to access the properties:

new AjaxUpload(thisId, {
    action: thisUrl,
    name: 'thisfile',
    onSubmit: function () { //Anonymous function so you can pass arguments
        imageObject[thisSubmit]("myArg"); //Square brackets here
    },
    onComplete: imageObject[thisCallback] //Square brackets here (no arguments)
});
James Allardice
  • 164,175
  • 21
  • 332
  • 312
1

I'm assuming the thisSubmit and thisCallback local variables are meant to be the names of the functions that exist on imageObject.

Do both call those methods using names from those strings, and pass in arguments, you use a combination of bracketed syntax and closures:

var imageObject = {
    sendImage : function(obj) {
        "use strict";
        var thisId = obj.attr('id');
        var thisSubmit = obj.attr('data-submit');
        var thisCallback = obj.attr('data-callback');
        var thisUrl = $('#' + obj.attr('data-url')).text();
        new AjaxUpload(thisId, {
            action: thisUrl,
            name: 'thisfile',
            onSubmit: function() {
                imageObject[thisSubmit](arg, anotherArg, etc);
            },
            onComplete: function() {
                imageObject[thisCallback](arg, anotherArg, etc);
            }
        });
    }
    // Presumably there are more methods here, or added later...
}
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
-1

you have to use call which call a function in js

onSubmit: function(file, extension) {
    imageObject.thisSubmit.call(undefined, file,extension);
},

see What is the difference between call and apply?

Community
  • 1
  • 1
amd
  • 20,637
  • 6
  • 49
  • 67