Search code examples
javascriptmethodsdojoscopeanonymous-methods

javascript classes scope and anonymous functions


I have a javascript class declared as shown below.. My problem is the aonymous function does not see the scope of the class. I can not reference the bb_obj from within the ajax call load callback..

Is there a way to do this?

Thanks in advance..

dojo.declare("sop.quote", null,
{
   bb_obj : new Object,

   stage1 : function()
   {
      dojo.xhrPost(
      {
         url      :  'go/module_service/transport.php',
         content  :  this.bb_obj,
         handleAs :  'xml',
         load     :  function(xml)
         {
            var status  = xml.getElementsByTagName("STATUS")[0].childNodes[0].nodeValue;
            var message = xml.getElementsByTagName("MESSAGE")[0].childNodes[0].nodeValue; 

            this.bb_obj.message = message;
         },
         error    : function()
         {
         }
      }
   }
}

Solution

  • this inside a XHR callback function refers to the XHR object. The only way to refer to bb_obj is by directly referring to the created object, in the same scope as the function. Because objects are passed by reference, the code below works as intended.

    Note to avoid confusion, I've declared the object using var bb_obj_obj={}. The bb_obj property refers to bb_obj_obj:

    • bb_obj_obj.message is changed
    • bb_obj points to bb_obj_obj, hence bb_obj.message refers to the same variable

    Code:

    var bb_obj_obj = {}; //new Object
    dojo.declare("sop.quote", null,
    {
       bb_obj : bb_obj_obj,
    
       stage1 : function()
       {
          dojo.xhrPost(
          {
             url      :  'go/module_service/transport.php',
             content  :  this.bb_obj,
             handleAs :  'xml',
             load     :  function(xml)
             {
                var status  = xml.getElementsByTagName("STATUS")[0].childNodes[0].nodeValue;
                var message = xml.getElementsByTagName("MESSAGE")[0].childNodes[0].nodeValue; 
    
                bb_obj_obj.message = message; //Without `this`
             },
             error    : function()
             {
             }
          }
       }
    }
    

    An alternative method consists of saving this in a variable, eg. $this:

    ...
    stage1 : function()
    {
        var $this = this;
        dojo.xhrPost({
         ...
         load     :  function(xml){
            var status  = xml.getElementsByTagName("STATUS")[0].childNodes[0].nodeValue;
            var message = xml.getElementsByTagName("MESSAGE")[0].childNodes[0].nodeValue; 
    
            $this.bb_obj.message = message; //Using `$this` instead of `this`
         },
    ...