2

I have the following code sample that im trying to wrap my head around

        $(document).ready(function () {

        test("load json", function () {

            length = 0; // length = 0

            $.getJSON("plugins/form.json", function (data) {
                length = data.fields.length; // length = 4
            });

            ok(length == 4, "length = " + length.toString()); // length = 0? wtf?
        });
    });

the 'length' variable does not persist when the $.getJSON runs. I cant figure out if its because its asynchronous or because the variable is out of scope.

5 Answers 5

3

If the getJSON method is running asynchronously, then the ok(... line will likely execute before the getJSON returns...thus length will always be 0...

could you not do this...

$.getJSON("plugins/form.json", function (data) {  
   var somelength = data.fields.length;  
   ok(somelength == 4, "length = " + somelength.tostring());  
});

that way it calls the ok function once the getJSON has returned with data...

Sign up to request clarification or add additional context in comments.

2 Comments

That's completely right but not enough, the test runner needs to be paused and resumed, check my answer and example
I wasn't familiar with QUnit...+1 your answer...but mine is still providing an answer to why the code isn't working (hopefully!)...
2

You should make an asynchronous test, and since you are using QUnit, you can use the stop method, make your assertions on the getJSON callback, and then resume the following tests:

$(document).ready(function () {

    test("load json", function () {
        stop();

        $.getJSON("plugins/form.json", function (data) {
            var length = data.fields.length;
            ok(length == 4, "length == " + length);
            start(); // resume tests
        });
    });
});

Or you can use the asyncTest method instead of test, which will implicitly make a call to stop:

//...
asyncTest("load json", function () {

    $.getJSON("plugins/form.json", function (data) {
        var length = data.fields.length;
        strictEqual(length, 4, "length"); 
        //...
        start(); // resume tests
    });
});
//...

Check a live example here and give a look to the source code here.

Comments

1

Its not because of scope issue, but because of this line run first

ok(length == 4, "length = " + length.toString());

before callback function from JSON

function (data) {
    length = data.fields.length; // length = 4
}

You need to put ok(length == 4, "length = " + length.toString()); function inside callback function of $.getJSON.

Comments

1

Yes, that would be because it's asynchronous.

test("load json", function () {

     // executes first

     $.getJSON("plugins/form.json", function (data) {

         // executes last (that is, "sometime later")

     });

     // executes second

});

Also, you should declare the variable as var length the first time, unless you want it to be global.

Comments

-1

Try this - $(document).ready(function () {

var length = 0; // length = 0
    test("load json", function () {

        $.getJSON("plugins/form.json", function (data) {
            length = data.fields.length; // length = 4
        });

        ok(length == 4, "length = " + length.toString()); // length = 0? wtf?
    });
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.