views:

438

answers:

3

I am having some trouble with the classic javascript local variable scope topic, but dealing with a JSON variable. I have looked at other questions here regarding the same thing, but nothing has matched my case exactly, so here goes. I have a class that I have made from javascript that has 3 methods: func1, func2, and func3. I also have a local JSON variable that is being set in one of the methods from an ajax call I am making with jquery, but is not set when I call a method that returns that local variables value. I know the ajax is working fine, b/c I can display the data that is being returned and being set to the json variable fine with no problem. It is only happening when I call another method that interacts with that JSON variable. Here is a basic version of my code:

   function func1(){
       func2();
    }

    function func2(){
       $.getJSON("http://webservice.mydomain.com/methodname&jsoncallback=?",
      function(data){
         this.z = eval("(" + data.d + ")");
      alert(data.d); //this displays the data!
      alert(this.z.ArrayProperty[0].Property1); //this displays 
                                                      //the correct data too!
      }
       ); 
    }

    function func3(){
       return this.z.ArrayProperty[0].Property1;
    }

    function myClass(var1, var2){
       this.x = var1;
       this.y = var2;

       this.z = "";

       this.func1 = func1;
       this.func2 = func2;
       this.func3 = func3;
    }

And then in my .html page, I am having the following code:

var obj = new myClass(1,2);

obj.func1("abc");
alert(obj.func3()); //ERROR: this.z.ArrayProperty is undefined

Any ideas?!?! I am racking my mind!

Thanks

A: 

I don't think "this" inside your callback is the same "this" that defined func2. Using the Prototype JavaScript library, you can use bind() to get around this.

You may be able to just add a new variable in func2, or use a bind function in whatever library you are using.

func2() {
    var me = this;
       $.getJSON("http://webservice.mydomain.com/methodname&jsoncallback=?",
             function(data){
                me.z = eval("(" + data.d + ")");
                    success = true;
                    alert(data.d); //this displays the data!
                    alert(this.z.ArrayProperty[0].Property1);
             }
       );       
    }
Norman
A: 

I could be completely wrong, but it look like the "this" variable is messing you up. "this" variable depends on how you call the function. It looks like you really don't want to be using that. Instead, I use:

func2() {
  var that = this;

Then later in the code use:

function(data){
  that.z = eval...
psayre23
+2  A: 

I don't think this is anything to do with scope.

Remember that the AJAX call is asynchronous so func3 is being called before the JSON has been returned and your anonymous function has had a chance to set this.z to anything.

Sam Hasler
You are spot on Sam. Now I just have to find a good way to get around that. Thanks!
Dan Appleyard