Scope of variables inside javascript
I have the following example code that I am trying to wrap 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?
});
});
variable 'length' is not saved when $ .getJSON is run. I can't figure out if this is its asynchronous or because the variable is out of scope.
a source to share
If the getJSON method runs asynchronously, then the ok (... string will probably run before getJSON returns ... so the length will always be 0 ...
Could you do this ...
$.getJSON("plugins/form.json", function (data) {
var somelength = data.fields.length;
ok(somelength == 4, "length = " + somelength.tostring());
});
this way it calls ok function after getJSON returns with data ...
a source to share
You have to do an asynchronous test, and since you are using QUnit you can use stop
, make your assertions in the callback getJSON
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 asyncTest
instead test
, which will implicitly make the call stop
:
//...
asyncTest("load json", function () {
$.getJSON("plugins/form.json", function (data) {
var length = data.fields.length;
strictEqual(length, 4, "length");
//...
start(); // resume tests
});
});
//...
Check out a live example here and see the source code.
a source to share
It's not because of the scope issue, but because of this line, it starts first
ok(length == 4, "length = " + length.toString());
before the callback function from JSON
function (data) {
length = data.fields.length; // length = 4
}
You need to put a function ok(length == 4, "length = " + length.toString());
inside a callback function $.getJSON
.
a source to share
Yes, that would be because it is asynchronous.
test("load json", function () {
// executes first
$.getJSON("plugins/form.json", function (data) {
// executes last (that is, "sometime later")
});
// executes second
});
Also, you must declare the variable as var length
the first time, if you don't want it to be global.
a source to share
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?
});
});
a source to share