I'm trying to call a REST API using for loop and store the output to an array. But the output shows in different arrays for each and every rest API call instead of everything in one array
for each (name in car.cars){
for(i=0; i<count;i++){
var arr = [];
var newid = car.cars[i].name;
var url = "myhost"
var method = "GET"
var response = "output from REST call"
arr.push(response)
}
}
But the output shows in different arrays for each and every rest API call instead of everything in one array
Where is "the output" there's nothing in your code.
Your Problem is that you're declaring the var arr = []; inside your for loop.
Initialize the array before the loop starts and just add your responses to that array.
Instead your creating a new array for each iteration of for(i=0; i<count;i++)
Take a step back and look at your code again. Where are you declaring your array? Inside the loop.
Next, ask yourself; what is the scope of that array? Only within the loop. Even if just in the outer loop, it won't stick around because as soon as that loop finishes, the array disappears.
Create the array and use it from outside the loops (both of them).
Further reading: Declaring variables inside or outside of a loop
UPDATE 4/30/2019: Thanks to #AuxTaco, I crossed out my inaccurate description of scope in JS. Please see the links in his comment for more reading on this!
Related
I have a simple array that I'm trying to iterate over but I'm apparently not understanding the 'for of' JavaScript loop. The following code returns exactly has it should;
const callOBJb = ['KD0NBH0BJ','W0DLKOBJ','WA0TJTOBJ'];
for (let i of callOBJb) {
console.log(i);
}
return: KD0NBHOBJ W0DLKOBJ WA0TJTOBJ
But the following code errors out with; "TypeError: i.getCenter is not a function. (In 'i.getCenter()', 'i.getCenter' is undefined)" because the variable 'i' does not resolve to one of the above.
for (let i of callOBJb) {
var Omiddle = i.getCenter();
}
When I manually type the variable in such as;
var Middle = W0DLKOBJ.getCenter();
It works just fine. What am I not understanding about how this should work?
I don't think I can use the ForEach here at least I'm not having any more luck than the for...of.
I was asked what the resolved variable for W0DLKOBJ might look like.
alert(JSON.stringify(KD0NBHOBJ));
{"_southWest":{"lat":39.204385,"lng":-94.60714},"_northEast":{"lat":39.20646,"lng":-94.60481}}
This works:
var Middle = W0DLKOBJ.getCenter();
because this:
W0DLKOBJ
is different from this:
'W0DLKOBJ'
If the array should contain the variable values and not string literals, don't use quotes:
const callOBJb = [KD0NBH0BJ, W0DLKOBJ, WA0TJTOBJ];
The callOBJb variable is an Array of strings, and when you use for..of statement to perform a loop iteration, for each item in your iterable object you will get item at deposition corresponding to the time to loop bloc code is execute.
In you case as all items in the callOBJb array is simple string, javascript String.prototype Object doesn't define a function named getCenter that is the reason why you are getting
"TypeError: i.getCenter is not a function. (In 'i.getCenter()', 'i.getCenter' is undefined)
let callOBJb = ['KD0NBH0BJ','W0DLKOBJ','WA0TJTOBJ'];
for(let item of callOBJb){
console.log(typeof item, item);
}
As you can see on each iteration the typeof item is always string.
I went back to the php and redesigned the output to make conversation to Javascript easier. By doing that I was able to iterate through the values using "for (let val of callOBJb)" successfully.
The solution came in how I received the data from PHP to start with. When I changed the definition to; const callOBJb = <?php echo "[$callOBJb]" ?> to include the square brackets and then used; for (let val of callOBJb) {...etc all of the variables resolved properly.
I have made a function that randomizes the order of answers in a quiz builder.
I pass in an array, the elements contain a question, some answers, and some other info. The correct answer is always in index 2 and this position needs to be randomized before a quiz question is generated.
function randomiseAnswers(question)
{
//return an array with 5 elements, 0 to 4. Element 4 contains the index of the correct answer.
//INPUT PARAM = Topic; Question; Correct; Distractor; Erroneous; Erroneous; Resource
var correct = question[2];
var answers = [];
var temp = question;
temp.splice(2,4);
shuffleArray(answers);
answers.push(answers.indexOf(correct))//make sure final element is the position of the correct answer
//Logger.log(answers);
return answers;
}
When I use this function, the original array that is passed to the function is being modified even though I only use a splice on a copy of the array called 'temp' inside the function.
When I replace the splice method with some push()es instead the original array remains intact and the function works as intended.
Why would splice modifying the array 'question' when it is only being used on a temporary array?
Use let/const instead of var. Var is outdated
To solve your problem:
const temp = [...question]
I hope you can help me with this hopefully stupid problem.
I try to do the following:
creating array with data
looping through this array within a for loop (based on array.length)
create new object based on data in array
So far I got the following:
create array
loop through array
create one object based on my constructor
The problem is, the array has a length of 4 and should therefore create 4 objects but it creates only one. If I remove the creation of the object and just log "i' it works, but in the original intention it ends after the first
The loop looks as follows:
for(i=0;i<array.length;i++)
{
newObj[i]=new ObjectName(array[i].param1,array[i].param2,array[i].param3)
}
I have no idea why it ends after the first run and I also don't get an error displayed when looking into firebug.
Cheers
Does changing the
newObj[i] =
to
newObj.push(...)
help?
Also how is newObj initialized?
newObj = []
for (i = 0; i < (stringNums.length); i++) {
Dictionary[stringNums[i]] = stringNums[i].length;
}
I've got an indexed array of urls nested inside of another array that uses strings as its keys. I need to extract information from both arrays and I'm using the following loops.
// Loop through the elements in the associative level to get a count of its items
var keyCnt = 0;
for(key in serviceCategories) {
keyCnt++;
}
// Then loop through it again, this time nesting another for loop to get at the inner/indexed arrays
for(key in serviceCategories) {
var currCat = key;
for (var i = 0; i < keyCnt; i++) {
$.ajax({
url: serviceCategories[currCat][i],
success: function(data) {
parsePageCont (data, currCat);
}
});
}
}
}
This code works ok for the first element of the first array. It cycles through its inner array and excecutes the ajax call for every url with no problem. But then, when it finishes with the first element of the first array it doesn't proceed to the second one and fetch IT'S inner array data.
I hope that explanation wasnt too messed up.
You can see the full code here for more clarity: http://jsfiddle.net/FvP5f/
Assuming your data structure is an object with arrays for properties, you would do it like this.
serviceCategories has to be an object, not an array. Javascript doesn't have associative arrays. It has objects for storage by key and iteration by key. Arrays indexes are numeric.
You have to actually iterate over the length of each embedded array.
You can't refer to the key variable in the success handler because that gets called long after the loops so it's value has changed. To solve that problem, we put the key in a context object that will get set as the "this" pointer for the success handler so we can get back to the key.
Here's the code to solve those issues:
// assume data is of this structure (where I've shown numbers here, they are actually URLs)
serviceCategories = {
houses: [1,2,3,4],
cottages: [5,6,7,8],
hotels: [8,9,0,1],
apartments: [2,2,3,4,5,7,8,9]
};
for (key in serviceCategories) {
if (serviceCategories.hasOwnProperty(key)) {
var array = serviceCategories[key];
// got the next array, iterate through it
for (var i = 0; i < array.length; i++) {
var context = {};
$.ajax({
url: array[i],
context: {key: key}, // can't refer to key in success handler, so we sest it as context
success: function(data) {
parsePageCont(data, this.key);
}
}
});
}
}
Well, one problem seems to be that you are assuming that the second dimension of your array is always the same size (ie keyCnt). You also seem to be counting the wrong direction, by which i mean you would get two (inGoodHands and spaRituals), while you are using it for the second index which is 2 for inGoodHands, and 3 for spaRituals)).
It seems like you should be doing something like this:
for(x in serviceCategories) {
for(y in serviceCategories[x]) {
call ajax for serviceCategories[x][y]
}
}
Javascript scope is the function, not the block. While you can put var curcat inside a for loop it's important to understand that you are not creating a different variable for each iteration.
This means that all the closures you are creating in the loop will actually be based on the same variable so what you probably observed is not that only the first works, but that all of them worked by they were all working on the last key.
The solution for creating a local scope in javascript is to use a local function; instead of
(function(data){ parsePageCount(data, curcat); })
you could use
(function(x){return function(data){ parsePageCount(data, x); };})(curcat)
where the name x has been used instead of curcat to make clear the distinction.
This variable will be indeed separate for each of the created closures.
I can't figure out what's going on here... I'm trying to copy an array, and then shuffle and join the copy, but it just isn't cooperating.
I have a JS file and am initializing a new array at the top:
var myArray = [];
On load of this JS file, I am pulling data from the Facebook API and stickin' the results in myArray with some HTML around it.
I then have a function which I call on button click which creates a new variable from myArray and then joins and prints out the text in a div element:
var namesList = myArray;
namesList.join('');
$('#my_div').text(namesList);
It's obviously been simplified, but the premise is the same.
My problem is, the array is not joining like it should. It remains in array form and nothing I've tried has fixed this. I've also tried:
var namesList = myArray.slice();
and
var namesList = myArray.slice(0);
to no avail.
HOWEVER: I can manipulate myArray with no problems in the same function and get the results I need. The problem with that is, I need to be able to shuffle the array each time the function is called and then print it out as text; this is why I am copying it in the first place.
For the life of me I can't figure out why this isn't working. All I need to do here is to create a copy of the variable within the scope of the function I'm calling, shuffle it, join it, and print it.
How do I fix this? OR, is there a better alternate? Many thanks in advance!
The join() method returns a string rather than modifying the array reference - you need to change your code to this:
var namesList = myArray;
namelist = namesList.join('');
$('#my_div').text(namesList);
That's because namesList still is an array. join() returns a string, which you should use:
var namesList = myArray.join('');
$('#my_div').text(namesList);
namesList.join('');
This joins the array then throws the result away. You want
namesList = namesList.join('');