Assigning multiple variables from a looping prompt input in Javascript? - javascript

I'm writing a very simple program, which asks for a number of names depending on how many tickets are needed. I cannot find a way to change the variable that the prompt input is assigned to every time the loop runs. Is there a way to do this? Below is the current loop I'm using.
while (ticketsNeeded != 0) {
name = prompt("Enter the name of attendee #" + ticketsNeeded);
ticketsNeeded--;
}
For example, if three tickets are needed, the user will be prompted for three different names; however, they are all saved to the same variable and I'd like to have them uniquely assigned so I can later use them.

An array will solve your problem:
var names = []; // initialize empty array
var ticketCounter = 0;
while (ticketsNeeded != 0) {
names[ticketCounter++] = prompt("Enter the name of attendee #" + ticketsNeeded);
ticketsNeeded--;
}

Related

How to make For loop wait for Firebase Database response?

I have a function that receives an object array. The array looks like this:
var receivedObjects = [{nuih329hs: 100}, {8suwhd73h: 500}, {2dsd73ud: 50}, {9u238ds: 200}];
Each key is an ID, and each value is a number.
The objects are in a set order and what I want to do is iterate through the objects and define each value as a variable, which I'll then use when creating a html row.
The problem I'm having is, I have to make a call to a Firebase database inside this iteration code, the result is that while a row is successfully being created for each object value, the value entered into each row is always the same (the last/most recent value in the object array), so in the above case the number 200 is appearing in all four rows.
I think this might be happening because maybe all the iterations are completing before the first Firebase call is even completed, meaning the variable currentValue (which I'm entering into the rows) is set at the last value in the array before the first Firebase call is made.
Note: There is another array (called listOfIds) which contains Firebase IDs, I'm able to successfully use each ID from this array as a variable to use in the Firebase call, var currentID is that variable.
This is the function:
function populateTable(receivedObjects){
var receivedObjectsLength = receivedObjects.length;
// Note: an object array called listOfIds exists here (containing Firebase IDs to be used for querying Firebase), it's referenced below.
for (var i = 0; i < receivedObjectsLength; i++) {
// listOfIds is an Object array
var currentID = Object.keys(listOfIds[i]);
var term = (Object.keys(receivedObjects[i])[0]);
var currentValue = receivedObjects[i][term];
//The following line is showing the correct ID and Value for each iteration:
console.log("The current ID is: "+currentID+" and the current value is: "+currentValue);
firebase.database().ref('/users/' + currentID).once('value').then(function(child) {
// This is where the rows are created, ``currentValue`` is used here, but it's appearing as the same value in every row.
// The next line is showing the correct current ID, but it's showing the currentValue as "200" in every row.
console.log("The current ID is: "+currentID+" and the current value is: "+currentValue);
});
}
}
I'm very confused, because I thought the Javascript iteration code would wait until the data gets returned from the Firebase call, but it seems this isn't the case? How can I change my code so that the line console.log("The current ID is: "+currentID+" and the current value is: "+currentValue); inside the Firebase call success function will show the correct currentValue?
Instead of making the loop wait, you can use a function to put currentID and currentValue into their own scope so that they don't get overwritten with each iteration:
function getUser(currentID, currentValue) {
return firebase.database().ref('/users/' + currentID).once('value').then(function(child) {
console.log("The current ID is: "+currentID+" and the current value is: "+currentValue);
});
}
In your loop:
for (var i = 0; i < receivedObjectsLength; i++) {
...
getUser(currentID, currentValue)
}

Display different text everytime you call onclick function

I have this code where I am trying to pull users from my firebase database:
function pullFromDB(){
usersRef.on('value', function(snapshot) {
function next_user(){
for (user in snapshot.val().users){
document.getElementById("users").innerHTML = user
}
}
So far it will return just one of the users as I believe it must be going through the whole users array and then putting the last name into the "users" element.
How can I iterate to the next item in the array and display a different name every time I click a button?
I have no idea what's return from DB but first try the console.log() to see what's the type of result. This will give you the answer if you are working on array or other data type.
Then if it's an array, your code:
for (user in snapshot.val().users){
document.getElementById("users").innerHTML = user
}
It iterates the whole array and .innerHTML puts user string as the last iteration. If you want to change it each time you click a button you need a variable that will contain inteager of index that's currently aplied to id="users".
Then for each click you need to increase the variable by one.
Here is an example of working with arrays in JS. http://www.w3schools.com/js/tryit.asp?filename=tryjs_array_element
Your are iterating through the whole array and only the last one is possible shown. You just need to assign an index and use it.
I don't know your remaining code, but by the given information, this should to the trick:
i = 0;
function pullFromDB(){
usersRef.on('value', function(snapshot) {
lastnames = Object.keys(snapshot.val().users); // get all keys, in your case the last names
function next_user(){
user = lastnames[i];
document.getElementById("users").innerHTML = user;
i++; // increase after click
// when you want to access more information of the user, you can do it like this (as an example)
// user_id = snapshot.val().users[user].id;
}

Storing multiple data entries into a javascript object?

In my program I have to prompt the user to enter customer info.
The information includes first name, last name, phone number, and grocery items (separate each array by a comma).
The prompt keeps asking user for info until user presses cancel or enters nothing.
ex:
peter,pho,123-324-2333, beans,carots,cereal
karen,smite,122-333-1223, milk,pudding
Each time the user enters input, I need to create an object to store the info, and each object needs a property grocery item. So I assume it goes something like this.
cust = prompt("enter customer info");
while(cust != null){
var array1 = cust.split(',');
var customer = {
custinfo:array1.slice(0,3),
items:array1.slice(3,array1.length)
}
cust = prompt("enter");
}
This works for the first customer, but how do I store many entries, I don't know how much customers the user will enter. I tried creating an array of objects, if that makes any sense , like customer[], but it didn't work.I split them into arrays for later use in my homework. Also how do I make the prompt run until user enters nothing?
If you want an ordered list of items, use an Array. You can combine this with a for loop. Here is an example
function ask_questions(questions) {
var answers = [],
i,
ans;
for (i = 0; i < questions.length; ++i) { // for infinite loop, `while (true) {`
ans = prompt(questions[i] || 'enter'); // default question
if (!ans) break; // cancel or blank ends questioning
answers[i] = ans; // do what you want with the data given
}
return answers;
}
The function ask_questions takes an Array (say arr) and prompts the user arr.length times, then returns the results of the prompts as another Array
var qs = ['enter customer info', null, 'enter2']; // null will cause message "enter"
qs.length = 4; // undefined will cause message "enter"
ask_questions(qs); // ["foo", "bar", "baz", "fizz"]
However, is this really the best data structure for you? You may do better with an Object which has useful property names rather than indices and ask them for specific pieces of data such as their name and address rather than leaving it up to them. If you leave it all up to them you could end up with their pet's life story and their favourite colour etc or even nothing at all.
Finally, prompt isn't a good UX, use <input> or <textarea>s in your final revision

When to compare several Arrays in a 'for' loop

I'm still quite new to Javascript and Google Apps Script, and I'm attempting to create a script that takes your friends steam IDs, loops over their owned games, lists them to a spreadsheet, and displays if someone owns a game or not.
I've achieved the first part, looping over all of the owned games for each ID and adding them to an array if they don't already exist in the array works perfectly using:
var steamId = ['SomeSteamIDs'];
var gameIds = [];
var games = [];
function getGames(){
for (var i = 0; i < steamId.length; i++){
var response = UrlFetchApp.fetch("http://api.steampowered.com/IPlayerService/GetOwnedGames/v0001/?key=**YourSteamKey**&steamid=" + steamId[i] + "&format=json&include_appinfo=1");//Steam URL.
Logger.log('Response Code: ' + response.getResponseCode());//Checks the request actually connected.
var data = JSON.parse(response.getContentText());//Gets the plaintext JSON response and converts it to an object.
for (var n = 0; n < data.response.games.length; n++){//For the length of the games list
var code = data.response.games[n].appid;
var name = data.response.games[n].name;
if (gameIds.indexOf(code) === -1){//if the AppID doesn't appear in the 'appId' array and sub-arrays
gameIds[gameIds.length] = code;//then put it in the appId array for comparison
games[games.length] = [code,name];// and add the AppId and Game to the games array for writting.
};
};
}
var range = sheet.getRange("A2:B" + (gameIds.length + 1));//+1 here to compensate for starting on line 2, instead of 1.
range.setValues(games);//Perform one write action
}
This works perfectly in compiling a master list of games that are owned across all SteamIDs, but I'm having difficulty in finding a way of checking off what games are owned by each Individual ID, and what is not.
Initially I was experimenting with adding a 'Yes/No' string to the 'games' array when running the 'getGames' function, but any solution I come up with looses data. If I compare the values too early, the 'gameIds' array doesn't contain all of the data, so the first SteamID misses out on comparing against any games that the last SteamID owns.
If I do it too late, the 'data' variable only contains the response data from the last SteamID it checked, so I miss out on checking what games the first SteamID owns.
I've read the answer at How to compare arrays in JavaScript? several times now, but I'm still trying to figure out if I can use it to solve my issue.
Is there a way for me to achieve what I'm looking for, and what would be the most efficient way?
I would approach this a bit differently. I would keep an object of gameList with game object keys by id that have a name property and then userList property that is an array of users attached to each game. This will do a few things for you. One, you can lookup the game in constant time now instead of looping to find it in the array (which indexOf does). Two, you now have a unique list of games (all properties of a games object) with an array of user ids (who owns them) for easy lookup. here's the code of what I'm describing
var steamIds = [],
gameList = {};
function getGames(){
steamIds.forEach(function(steamId) {
var response = UrlFetchApp.fetch("http://api.steampowered.com/IPlayerService/GetOwnedGames/v0001/?key=**YourSteamKey**&steamid=" + steamId[i] + "&format=json&include_appinfo=1");//Steam URL.
Logger.log('Response Code: ' + response.getResponseCode());//Checks the request actually connected.
var data = JSON.parse(response.getContentText());//Gets the plaintext JSON response and converts it to an object.
data.response.games.forEach(function(game) {//For the length of the games list
var code = game.appid;
var name = game.name;
if (!gameList.hasOwnProperty(code)) {
gameList[code] = {name: name, userList: [steamId]};
} else {
gameList[code].userList.push(steamId);
}
});
});
}
Here's and example of the end result of what the gameList will look like when it's done
gameList : {
123: {
name: 'Some Game',
userList: [80, 90, 52]
},
567: {
name: 'Another Game',
userList: [68]
}
}
Writing to the cells will change a bit but your information is now associated in a way that makes it easy to get information about a particular game or users that own it.

Declaring multiple scopes based on user input Angular-Rails

I have a $scope of 1 to 5 lists, depending on user input. In each list there will be an array of items. I have my list names as list1, list2....My problem is when I declare the $scope using $scope.list = []; it of course isn't going to know which list that would be. Since I am naming them statically and they have a limit of 5 I know I could declare each list. I feel that is a bit too heavy and not efficient. Is there a better way of declaring each list, based on the user input?
You can declare a property on your $scope dynamically - as with any other javascript object.
so, $scope.myList = [] is the same as $scope['myList'] = []
using your users input it should be simple to create these list properties on your scope from your users input.
Psuedo-code could be:
$scope.myButtonClick = function(){
// where userInput is a number
for (i = 0; i < userInput; i++){
$scope['list' + (i+1).toString()] = [];
}
}

Categories

Resources