This is to populate a table with the amount of results that are returned from the MediaWiki API query /api.php?action=query&list=querypage&qppage=BrokenRedirects
. The number of results is then added to the id, for example:
// BrokenRedirects
$.getJSON('/api.php?action=query&list=querypage&qppage=BrokenRedirects&format=json', function (data) {
$('#BrokenRedirects').text(data.query.querypage.results.length);
});
But as it's being repeated another 7 times I made the arguments for qppage into an array and used a for loop to shorten overall code.
var array = ['BrokenRedirects',
'DoubleRedirects',
'Unusedcategories',
'Unusedimages',
'Wantedcategories',
'Wantedfiles',
'Wantedpages',
'Wantedtemplates'];
for (var i = 0; i < array.length; i++) {
$.getJSON('/api.php?action=query&list=querypage&qppage=' + array[i] + '&format=json', function (data) {
$('#' + array[i]).text(data.query.querypage.results.length);
});
}
The first, unlooped, version works. But when I added a loop it didn't. The $getJSON
part executes, but it then fails to add the resultant data to the id. I ran it through JSLint which apart from complaining about functions in a loop and declaring var i
with var array
returned little help. I'm relatively inexperienced with javascript so thought perhaps a variable can't be used twice within a loop? Other than that, maybe something to do with using an id within a loop?
That's a classical problem : i
has the value of end of loop when the callback is called.
You can fix it like this :
for (var i = 0; i < array.length; i++) {
(function(i) { // protects i in an immediately called function
$.getJSON('/api.php?action=query&list=querypage&qppage=' + array[i] + '&format=json', function (data) {
$('#' + array[i]).text(data.query.querypage.results.length);
});
})(i);
}
2018 addendum:
There's now another cleaner solution in today's browsers: use let
instead of var
:
for (let i = 0; i < array.length; i++) {
$.getJSON('/api.php?action=query&list=querypage&qppage=' + array[i] + '&format=json', function (data) {
$('#' + array[i]).text(data.query.querypage.results.length);
});
}
Use Jquery $.each() to iterate over the array instead of a for loop.
For example:
$.each(array, function(_, value) {
var url = '/api.php?action=query&list=querypage&qppage=' + value + '&format=json';
$.getJSON(url, function (data) {
$('#' + value).text(data.query.querypage.results.length);
});
});
getJSON is an asynchronous ajax call
REFER: use synchronous ajax calls
You should write a function like -
function callUrl(value)
{
$.getJSON('/api.php?action=query&list=querypage&qppage=' + value + '&format=json', function (data) {
$('#' + value).text(data.query.querypage.results.length);
});
}
and then call it with some timeout option like -
setTimeout('callUrl(+ array[i] +)',500);
within the loop -
i.e.
for (var i = 0; i < array.length; i++) {
setTimeout('callUrl(+ array[i] +)',500);
}
Some delay for each call will be required here.
来源:https://stackoverflow.com/questions/15347750/getjson-and-for-loop-issue