Problems accesing external database inside For iterator - javascript

I have an array called countriesData that stores names for various countries, like this:
[Germany,France,Canada,Austria,Switzerland,Spain]
I'm trying to iterate over each element in that array, the idea is use each country in a query search over an external API, and then save the length of items in that external API. To put it simple, Im going through each country and counting how many items from that country are stored in an external database.
I have no problem accessing the database outside of the loop, however, I am unable to access it while inside the for iterator.This is my code:
for (var iter = 0; iter < countriesData.length; iter++) {
var obj = [];
var country = countriesData[iter]
var items;
var itemsCountry = 0;
$http.get("https://api.discogs.com/database/search?q={?country==" + country + " }&token=zwxZExVZTenjPTKumVeTDVRuniqhQLAxymdzSxUQ").then(function(response) {
items = response.data.pagination.items;
})
var str = "";
obj.push(countriesData[iter]);
obj.push(items);
for (var J = 0; J < myStats.data.length; J++) {
if (myStats.data[J].country == countriesData[iter]) {
itemsCountry++;
str += myStats.data[J].title + ", ";
}
}
obj.push(itemsCountry);
var str2 = str.substring(0, str.length - 2);
obj.push(str2);
newData.push(obj);
console.log("new obj : " + obj)
}
Basically, I need the var items to be updated acording to the length of the response data from http.get
This is an example of what I get once I console.log the obj:
France,,2,Thriller, D'eux
As you can see, the second element in the array is empty when it should have been an integer representing how many France related items where found in the database...
What is it that Im doing wrong? I get that the database is big and there might not be enough time for it to load. Any idead?
Thanks in advance :)

The problem is that your data call is asynchronous and hasn't completed before you try to push the data to the array.
function getCountryData(country) {
var obj = [];
var items;
var itemsCountry = 0;
$http.get("https://api.discogs.com/database/search?q={?country==" + country + " }&token=zwxZExVZTenjPTKumVeTDVRuniqhQLAxymdzSxUQ").then(function(response) {
items = response.data.pagination.items;
var str = "";
obj.push(country);
obj.push(items);
for (var J = 0; J < myStats.data.length; J++) {
if (myStats.data[J].country == countriesData[iter]) {
itemsCountry++;
str += myStats.data[J].title + ", ";
}
}
obj.push(itemsCountry);
var str2 = str.substring(0, str.length - 2);
obj.push(str2);
newData.push(obj);
console.log("new obj : " + obj)
})
}
for (var iter = 0; iter < countriesData.length; iter++) {
var country = countriesData[iter];
getCountryData(country);
}

Related

JavaScript TypeError: cannot read property 'split' of undefined

I am getting this typeError with split when I try to run this js. I am unsure of how to fix it, I defined it properly as shown in my textbook.
var current;
var string;
console.log("Enter words separated by spaces.");
prompt(string);
var array = [];
array = string.split(" ");
for(i = 0; i < array.length; i++)
{
var frequency = 0;
current = array[i];
for(i = 0; i < array.length; i++)
{
if(current === array[i])
frequency++;
}
console.log(current + " - " + frequency);
}
}
When running properly the function should produce an output like so: hey - 1.
It counts the frequency of each unique word and displays next to the word the amount of times it appears in the string. Any help would be greatly appreciated thank you.
the main problem is that you were not reading string in from your prompt. I have stored the result as s in my example below.
Also you were using i again in your second for loop. Use another letter for this (the convention is j):
var current;
var string;
var s;
console.log("Enter words separated by spaces.");
s = prompt(string);
var array = [];
array = s.split(" ");
console.log(array);
for(i = 0; i < array.length; i++){
var frequency = 0;
current = array[i];
for(j = 0; j < array.length; j++){
if(current === array[j]) frequency++;
}
console.log(current + " - " + frequency);
}
I hope this helps.
Just little mistakes:
store the prompt in string: string = prompt(string);
give second for loop another variable j, so i won't overwritten.
var current;
var string;
console.log("Enter words separated by spaces.");
string = prompt(string);
var array = [];
array = string.split(" ");
for (i = 0; i < array.length; i++) {
var frequency = 0;
current = array[i];
for (j = 0; j < array.length; j++) {
if (current === array[j])
frequency++;
}
console.log(current + " - " + frequency);
}
Instead of doing split, you can do .splice.
I believe this link is helpful.
However, first, you would have to search through the array for " ".
You can implement this through string.search(" "), which returns where the " " is found.
Furthermore, your syntax for prompt is wrong, it should be:
var something = prompt("Enter words separated by spaces.");

array displays the wrong thing

I want this code to display information from a text input from a form on an HTML page, using the array, it would take the information into an array, then display it back on a textarea, though each time it overrides the first line, not displaying right
var count = 0;
var input = document.forms["ShoppingForm"]["choiceTxt"].value;
function listChoice(){
count++;
var arr = new Array();
arr[count] = document.forms["ShoppingForm"]["choiceTxt"].value + "\n";
for(var i = 0; i <= arr.length; i++){
document.forms["ShoppingForm"]["listDisplay"].value = count + ". " +
arr[i] + "\n";
}
}
The issue seems to be with this line var arr = new Array();. Everytime it will create a new array.
Try my declaring the array outside the function.Also the seems to be no need of the count. The value can be simply pushed in the array
var count = 0;
var arr = [];
var input = document.forms["ShoppingForm"]["choiceTxt"].value;
function listChoice(){
arr.push(document.forms["ShoppingForm"]["choiceTxt"].value + "\n");
for(var i = 0; i <= arr.length; i++){
document.forms["ShoppingForm"]["listDisplay"].value = count + ". " +
arr[i] + "\n";
}
}

If value == 1 then get the next value in the array

var countries = [1,"DK",2,"USA",3,"Sweden",];
var languages = [2,"EN",3,"Swedish",1,"Danish"];
var population = [2,"300000000",1,"6000000",3,"8000000"];
In javascript, is there a way to look for a value in an array, for example if the value is 1, then take the next value in the array. Here it would be DK, Danish and 6000000.
I have this but think it should be way to do it more simple
for(var i = 1 ; i < countries.length; i = i+2){
var countryName = countries[i];
var countryId = countries[i-1];
for(var j = 0; j < languages.length; j = j+2){
if(languages[j] == countryId){
var positionSpokenLanguage = j + 1;
var spokenLanguage = languages[positionSpokenLanguage];
}
if(population[j] == countryId){
var positionPopulation = j + 1;
var totalPopulation = population[positionPopulation];
}
}
var message = "In "+countryName+" people speak "+spokenLanguage+
" and there are "+totalPopulation+" inhabitatns";
console.log(message);
}
As you are actually looking for a value in every other item in the array, there is no built in method for that.
If you know that the value is in the array, you can just loop until you find it:
var index = 0;
while (countries[index] != 1) index += 2;
var value = countries[index + 1];
Your data has an unintuitive format, which makes it a bit awkward to work with. If possible you should use a data format where you don't mix keys with values, for example an object:
var countries = { 1: "DK", 2: "USA", 3: "Sweden" };
Then you can just get the value using the key:
var value = countries[1];

Checking Duplicates Script

I want to display duplicates found from the sheet in a Browser.Msg box and send the duplicate strings via email.
Additionally extra column could be written to that row where status "DUPLICATE - YES" would be written. However just to get it via email / in a popup would be enough.
I have tried logging the data. I have tried setting variables.
function checkDuplicates() {
var sheet = SpreadsheetApp.getActiveSheet();
var dataRange = sheet.getRange("DATA!F2:F"); // Set Any Range
// "A:A" is for Column A
// And if you want to check duplicates for whole sheet then try this:
// var dataRange = sheet.getDataRange();
var data = dataRange.getValues();
var numRows = data.length;
var numColumns = data[0].length;
var dupes = false;
var okdupes0 = 0;
var nodupes0 = 0;
var totbookings0 = 0;
var formats = [];
var values = [];
for (var i = 0; i < numRows; i++) {
formats[i] = [];
for (var j = 0; j < numColumns; j++) {
formats[i][j] = 'WHITE';
if (data[i][j] != '') {
values.push([data[i][j], i, j]);
}
}
}
var numValues = values.length;
for (var k = 0 ; k < numValues - 1; k++) {
if (formats[values[k][1]][values[k][2]] == 'WHITE') {
for (var l = k + 1; l < numValues; l++) {
if (values[k][0] == values[l][0]) {
formats[values[k][1]][values[k][2]] = 'RED';
formats[values[l][1]][values[l][2]] = 'RED';
var dupes = true;
}
}
var okdupes = okdupes0++;
}
var totbookings = totbookings0++;
}
if (dupes) {
// var okdupes = okdupes -1;
var nodupes = totbookings - okdupes;
var emailAddress = "myemail#gmail.com"; // First column
var message = + nodupes + " Duplicate voucher(s) has been found from the system. Duplicate vouchers has been marked with red color."; // Second column
var subject = "System: " + nodupes + " Duplicate Voucher(s) Found!";
MailApp.sendEmail(emailAddress, subject, message);
Browser.msgBox('Warning!', ''+ nodupes +' Possible duplicate voucher(s) has been found and colored red! Please contact the rep who has made the sale. '+ totbookings +' bookings has been scanned through for duplicates.', Browser.Buttons.OK);
} else {
Browser.msgBox('All good!', 'No duplicate vouchers found.', Browser.Buttons.OK);
}
dataRange.setBackgroundColors(formats);
}
You could convert the array of values to a string, then use match to count occurrences.
This code works to find duplicates, even from a two dimensional array. It doesn't determine what cell the duplicate came from. The values of all the duplicates are put into an array.
function findDups() {
var testArray = [['one','two','three'],['three','four','five']];
var allDataAsString = testArray.toString();
Logger.log('allDataAsString: ' + allDataAsString);
//Create one Dimensional array of all values
var allDataInArray = allDataAsString.split(",");
var pattern;
var arrayOfDups = [];
for (var i = 0;i<allDataInArray.length;i++) {
var tempStr = allDataInArray[i];
// the g in the regular expression says to search the whole string
// rather than just find the first occurrence
var regExp = new RegExp(tempStr, "g");
var count = (allDataAsString.match(regExp) || []).length;
Logger.log('count matches: ' + count);
if (count > 1 && arrayOfDups.indexOf(tempStr) === -1) {
arrayOfDups.push(tempStr);
};
};
Logger.log('arrayOfDups: ' + arrayOfDups);
Browser.msgBox('Thest are the duplicate values: ' + arrayOfDups);
//To Do - Send Email
};
The above example code has a hard coded two dimensional array for testing purposes. There are two occurrences of an element with the value of 'three'.

Loop & search through ALL items in localStorage

I'm trying to loop through localStorage to get ALL items through localStorage.length that works with my search algorithm. If i change: i < localStorage.length inside the for loop to simply a number, i.e: for (i=0; i<100; i++) instead of: (i=0; i<=localStorage.length-1; i++), everthing works. However, I do realize the problem might lie in the search algorithm.
The code getting all items:
var name = new Array();
for (var i = 0; i <= localStorage.length - 1; i++) { // i < 100 works perfectly
key = localStorage.key(i);
val = localStorage.getItem(key);
value = val.split(","); //splitting string inside array to get name
name[i] = value[1]; // getting name from split string
}
My working (!?) search algorithm:
if (str.length == 0) {
document.getElementById("searchResult").innerHTML = "";
}
else {
if(str.length > 0) {
var hint = "";
for(var i=0; i < name.length; i++) {
if(str.toLowerCase() == (name[i].substr(0, str.length)).toLowerCase()) { //not sure about this line
if(hint == "") {
hint = name[i];
} else {
hint = hint + " <br /> " + name[i];
}
}
}
}
}
if(hint == "") {
document.getElementById("searchResult").innerHTML=str + " står inte på listan";
} else {
document.getElementById("searchResult").innerHTML = hint;
}
}
What is wrong with my localStorage.length, or what is wrong with the search algorithm?
localStorage is an object, not an array.
Try for(var i in window.localStorage):
for(var i in window.localStorage){
val = localStorage.getItem(i);
value = val.split(","); //splitting string inside array to get name
name[i] = value[1]; // getting name from split string
}
Problem now SOLVED. The issue was that each time data was saved to localStorage, one extra empty item was stored at the bottom of the local db as a consequence of an incorrectly written for loop (in the setItem part.) arrayIndex < guestData.length should have been arrayIndex < guestData.length-1. arrayIndex < guestData.length-1 stores all items without creating an empty item at the bottom of the database which later messed up the search algorithm, as the last value to be search was undefined (the empty item).
print all localStorage items
and exclude the internal properties and methods.
for(var key in localStorage){
if(localStorage.hasOwnProperty(key)) {
console.log(key + ' : ' + localStorage.getItem(key));
}
}

Categories