clarkk
clarkk

Reputation: 27669

js callback function

How can I callback to a function in an object?

json_post('get_tracks', 'json.request.php?get=tracks', 'genreId='+id+'&perPage=70&page=1', 'rtn_tracks');

Instead of making a callback to rtn_tracks() I want to do it to this.rtn()

How can I define this in the callback string?

Here is the code:

function stream_tracks(){
 this.get = function(id){
  json_post('get_tracks', 'json.request.php?get=tracks', 'genreId='+id+'&perPage=70&page=1', 'rtn_tracks');
 };

 this.rtn = function(json_obj){
  this.cnstr(json_obj);
 };

 this.cnstr = function(json_obj){
  alert('test');
 };
}
Stream_tracks = new stream_tracks();

var XMLHTTP = {};
function json_post(request_uid, uri, get_str, callback_function, callback_var){
 request_uid += Math.floor(Math.random()*999999).toString();

 if(window.XMLHttpRequest){
  XMLHTTP[request_uid] = new XMLHttpRequest();
 }
 else if(window.ActiveXObject){
  XMLHTTP[request_uid] = new ActiveXObject('Microsoft.XMLHTTP');
 }

 XMLHTTP[request_uid].open('POST', uri, true);
 XMLHTTP[request_uid].setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
 XMLHTTP[request_uid].onreadystatechange = function(){
  if(XMLHTTP[request_uid].readyState == 4){
   if(callback_function){
    eval(callback_function+'('+XMLHTTP[request_uid].responseText+(callback_var ? ', callback_var':'')+')');
   }
  }
 }
 XMLHTTP[request_uid].send(get_str);
}

Upvotes: 1

Views: 1035

Answers (3)

Frode
Frode

Reputation: 5710

You can pass functions as objects in Javascript, you don't need to pass the function name and use eval. If your callback should be called as a member of a class, you need to pass along the class instance as well. E.g. add a callback context argument to your json function:

function json_post(request_uid, uri, get_str, callback_function, callback_var, callback_context){
    /*... snip ...*/
    XMLHTTP[request_uid].onreadystatechange = function(){
        if(XMLHTTP[request_uid].readyState == 4)
        {
            if(callback_function){
                /* The call() function lets you call a function in a context */
                callback_function.call(
                    callback_context || this,
                    XMLHTTP[request_uid].responseText, 
                    callback_var
                );
            }
        }
    };
    XMLHTTP[request_uid].send(get_str);
}

Then you would call it like so:

json_post('get_tracks', 'json.request.php?get=tracks', 'genreId='+id+'&perPage=70&page=1', 
    this.rtn, // callback function
    null, // callback var
    this // callback context
);

Here's a good tip though: Use a framework! It will make your day a lot easier.

Upvotes: 0

Coin_op
Coin_op

Reputation: 10708

Ok so there are a couple of things that you need to do and it might make more sense if you have a read about closures.

Firstly you'll need to make a reference to the this variable so you can access it inside your callback without overwritting it.

function stream_tracks(){
   var obj = this;

Then if you want to refer to properties of that class/object from within its other methods you just use obj.this.

The second thing you should do is pass the callback as a function not as a string. It will also be more efficient as you will be able to do away with the eval function.

 this.get = function(id){
  json_post(
       'get_tracks',
       'json.request.php?get=tracks',
       'genreId='+id+'&perPage=70&page=1',
       function(){ obj.rtn(); }
     );
 };

Wrapping the callback in the anonymous function forms the closure and allows the function to use the variables from class. Also if you do it this way you can pass any parameters through at the same time as the function and do away with the extra parameters in the parent function.

Upvotes: 0

David Mårtensson
David Mårtensson

Reputation: 7600

Instead of using a string for callback, use a method.

var my = {
    start : function (s, callback) {
        callback(s);
    },
    callback: function(s) {
    }
}

You cannot use:

my.start("Hello World", my.callback)

Since this will cause the method to be processed without connection to the object my but you can do this.

my.start("Hello World", function(s) { my.callback(s); });

Upvotes: 1

Related Questions