1

I am basically trying to alter an object outside of my ajax callback but the results are not as I had initially expected. I have simplified my project to a very easy to understand example, but there is clearly something I am not grasping.

Here is the function that contains the ajax request and callback:

var testFun = function(obj){
    $.get("test.xml",function(xml){
    //parse xml here...
    obj.name = "B";
    });
}; 

This is the code that is outside of the function:

var o1 = new Object();
o1.name = "A";
    console.log(o1);
testFun(o1);
    console.log(o1);

I would have expected to have an output as such:

Object {name: "A"}
Object {name: "B"}

But Instead am given the output:

Object {name: "A"}
Object {name: "A"}

From what I understand the object is passed as a copy of a reference of the object, so any attribute changes should stick. What am I missing here and how can I actually change that object in the callback?

EDIT: This is how I solved the problem thanks to this post This is the function being called making the ajax request

function testFun(obj){
    return $.get("test.xml",function(xml){
    obj.name = "B";
    });
}

This is the code calling the function

var o1 = new Object();
o1.name = "A";
    console.log(o1);
testFun(o1).done(function(result){
    console.log(o1);
}).fail(function (){
    console.log("error");
});

And this is the expected and actual output:

Object {name: "A"}
Object {name: "B"}
Community
  • 1
  • 1
Wobby
  • 21
  • 2
  • 5
    It's because the `$.get` function is asynchronous. This means the second `console.log(o1)` is executed *before* the `obj.name` is set to `B`. All logic that relies on the data retrieved by the request needs to be placed in the `$.get` callback function. – Rory McCrossan Jul 16 '15 at 12:55
  • 1
    [Related](http://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-asynchronous-call), or possibly duplicate if you're trying to set the `name` based on something in the returned data. – James Thorpe Jul 16 '15 at 12:56
  • `obj.name = "B";` here `obj` not the same object. and one more thing i need to say console statements runs before your ajax finishes. so output is correct. – Jai Jul 16 '15 at 12:59

1 Answers1

3

If you want your console.log to work in the second case, you'll have to put it either inside a function that will be called inside your $.get function or directly inside the $.get function. It is currently not working because as said in the comments bellow your post, the $.get function is asynchronous. I remember that you could force it to be synchronous by putting the attribute "async" to false or something...

EDIT : As mentioned by James Thorpe, you should avoid forcing synchronous requests (see the comment below)

This should work.

var o1 = new Object();
o1.name = "A";
printMyObject(o1);
testFun(o1);

var testFun = function(obj){
    $.get("test.xml",function(xml){
    //parse xml here...
    obj.name = "B";
    printMyObject(obj);
    });
}; 

function printMyObject(obj){
    console.log(obj);
}
mrtna
  • 191
  • 8
  • 1
    Regarding synchronous requests - [the spec](https://xhr.spec.whatwg.org/#sync-warning) says they're in the process of being deprecated and removed. Chrome (at least, not sure of other browsers) already displays a warning when you use them. I wouldn't introduce them into any new code at this stage. – James Thorpe Jul 16 '15 at 13:08
  • `async:false` is a terrible practice as it blocks the UI . There is never any need to use it and as noted browsers are deprecating it – charlietfl Jul 16 '15 at 13:12