Lonneberga
Lonneberga

Reputation: 13

One variable lost after ajax call. The other found

Inside a function I run the following code:

var docTypeWorkArea = $(this).parents("#docTypeWorkArea");
    var workArea = GetWorkArea($(this));
    var name = workArea.find("#documentType :selected").text();
    var typeId = workArea.find("#documentType :selected").val();
    var nOrder = $(this).parents(".documentTypes").find("[rowId]").length + 1;
    $.ajax({
        type: "POST",
        url: "../Component/SaveDocumentType",
        cache: false,
        async: false,
        data: {
            name: name,
            nOrder: nOrder,
            typeId: typeId
        },
        success: function (result) {
            var newRowElement = workArea.find("#trNewRowDocType");
            newRowElement.show();
            newRowElement.before(result);
            docTypeWorkArea.remove();
        }
    });

When I set a breakpoint in the success function and try to call the variable "typeId" in the console (Google Chrome) it comes up as undefined. But the variable "workArea", which is also defined before the Ajax call, still has its value. What is the difference between these two variables that make it so?

Upvotes: 0

Views: 486

Answers (1)

Aditya Singh
Aditya Singh

Reputation: 116

Understanding how JavaScript closure works should help here:

Only the variables used by the inner function are put into the closure scope.

Let's see the following example:

var functionOne = function(){
    var a = 1,
        b = 2,
        c = 3;
    function functionTwo(){
       console.log("b = " + b); //put debug point here
    }
    functionTwo();
}
functionOne();

Here the outer function 'functionOne' has 3 local variables a,b and c. The inner function 'functionTwo' can access all these variables, however, only 'b' is actually used here, hence, only b will be put in closure scope when it is created by the JavaScript engine. This helps in reducing the memory footprint.

If you put a debug point where I have mentioned in the code, and type 'b' in your console, you will get b's value, but if you type 'a' or 'c', you'll get undefined.

If you add usage of 'c' or 'a' inside the inner function 'functionTwo', like this:

var functionOne = function(){
    var a = 1,
        b = 2,
        c = 3;
    function functionTwo(){
       console.log("b = " + b); //put debug point here
       console.log("c = " + c);
    }
    functionTwo();
}
functionOne();

Now you will be able to see their value's in the console, at the specified debug point. Because now they are also being actually used by the inner function.

That is why you are able to access 'workArea' but not 'typeId'. Because 'typeId' is not used in the success function.

Use 'typeId' in the success function and you'll be able to access that too in the console while debugging.

success: function (result) {
    var newRowElement = workArea.find("#trNewRowDocType");
    newRowElement.show();
    newRowElement.before(result);
    docTypeWorkArea.remove();
    console.log("typeId: " + typeId);
}

Upvotes: 2

Related Questions