Need to loop again depending on a condition javascript - javascript

Hi I'm making a javascript script which now is getting really hard to edit, and hard to understand for other people, I'll put it here hoping someone can understand it and give some advice or help
function fetchMember(id, select, sitename, total) {
return function() {
progress();
$.ajax({
type: 'POST',
url: "script.php",
data: $("#fetch").serialize() + "&id=" + id,
success: function(data) {
isUser = ($(data).text().indexOf("Invalid User") == -1);
if (isUser) {
username = $(data).find(".normal").text();
saved = id - invalid;
$.ajax({
type: 'POST',
url: "save.php",
data: {'username': username},
success: function(data) {
$("#test").append(id+" "+data + "<br />");
select.text(sitename+"("+saved+"/"+total+")"); //Updating numbers of fetched profiles on the frontend
}
});
}
else
invalid++; //loop again here because a user wan't valid
progress();
}
});
}
}
for (i = 0; i < members; i++) {
fetched++;
setTimeout(fetchMember(fetched, select, sitename, total), wait*i);
}
basically what I need to do is to loop again if at the end of the operation there are some invalid users, any help is really appreciated

I wonder if this code would help you, though it's not completely adapted for your case and wasn't tested. The main principle is the recursive call of memberFetch function. No need for timeouts in this case - it won't make any new requests to the server until it got a response for the last one. Feel free to ask any questions, but please try to experiment yourself :)
var currentId = 0; // Current member id
var membersNum = 10; // There are 10 members from 0 to 9
var neededValidUsersNum = 5; // We need only 5 valid users...
var valudUsersNum = 0; // ... but now we have 0 of them
// Let's make an array of all possible id's
// It will be a queue - we will try to fetch the first id
// In case of success - save data, remove that id from the queue, fetch the nex one
// Otherwise - put it at the back of the queue to try it again later
var possibleIds = [];
for (var i = 0; i < membersNum; i++) {
possibleIds.push(i);
}
// Fetched user data storage
var userData = {};
function fetchMember(id) {
var data = "some data";
$.post('script.php', data)
.done(function(responseData){
onFetchMemberDone(id, responseData);
})
.fail(function(){
onFetchMemberFail(id);
});
}
function onFetchMemberDone(id, responseData){
// Save recieved user data
userData[id] = responseData;
// Bump valid users num
valudUsersNum++;
// If there are not enough valid users - lets continue:
if (valudUsersNum < neededValidUsersNum) {
// Remove valide user from the queue (it was the first one)
possibleIds.shift();
// try to fetch the next one
var nextPossibleId = possibleIds[0];
fetchMember(nextPossibleId);
}
}
function onFetchMemberFail(id){
// add failed user to the end of the queue
possibleIds.push(id);
// try to fetch the next one
var nextPossibleId = possibleIds[0];
fetchMember(nextPossibleId);
}
// Lets launch the cycle! It doesn't look like one because it works through recursive calls
onFetchMember(0);

Related

Increase a variable by 1 in loop for Javascript

I have been writing javascript/jquery for about 2 days so I know very little. I have a set of variables that I am pulling from a page. I then write back to a database using API a duplication of that information x number of times. I am using a loop to complete the x number of times. I have a variable called newBar. It starts out being defined by adding 1 to another variable called curBar. What I am having trouble with is I need newBar to increase by 1 each time the loop is completed. I can't seem to wrap my head around how to accomplish this.
$(document).on('Start.view-render.view_536', function (event, view, data) {
var curBar = Start.models['view_536'].toJSON().field_173;
var barCount = prompt("How many total barcodes to generate?");
var loopCount = --barCount;
console.log( loopCount );
var newBar = ++curBar;
// Add a button to execute the action
$('#' + view.key).prepend('<button id="copy-button">Duplicate Barcodes</button>');
var duplicateInventory = {
field_170: data.field_170_raw[0].id, //Customer
field_171: data.field_171_raw[0].id,//inbound order
field_173: newBar,//barcode
field_178: data.field_178_raw[0].id,//Product
field_185: data.field_185,//product type
//field_443: data.field_443_raw[0].id > 0 ? data.field_443_raw[0].id : "",//batches-order item
field_175: data.field_175,//date received
field_186: data.field_186,//semi-finished weight
field_176: data.field_176,//Inbound Container #
field_177: data.field_177_raw[0].id,//warehouse
field_183: data.field_183,//inbound verified
field_221: data.field_221_raw[0].id,//order item
//field_352: data.field_352_raw[0].id > 0 ? data.field_352_raw[0].id : "", //STO
};
// Add the duplicate function to the button we just added
document.getElementById('copy-button').addEventListener('click', function () {
for(var i = 0; i < loopCount; i++){ //start duplicate loop
$.ajax( {
url: 'https://api.somedomain.com/v1/objects/object_10/records/',
type: 'POST',
headers: {'X-Application-Id': 'xxxx', 'X-API-Key':'xxxx'},
data: duplicateInventory,
success: function(response) {
// alert('Record Copied!');
}
});
}//End of Loop
});
});

Data in a variable disappears after while loop

I am getting data from my API like this:
function getWeight (username) {
/* This function takes a username as a parameter,
then it calls the API URL using the username
so that it gets the weights of that particular
user.
*/
var weights;
$.ajax({
type: 'GET',
url: '/weight/api/get_weight_data_admin/'+username,
dataType: 'json',
async: false,
success: function (data) {
weights = data
}
});
getWeightPlots(weights);
}
The above code is working as expected when I do console.log(weights) it shows me exactly what I expect:
The problem lies in the code below; the list which I create in the function below, and append values to it inside the while loop, after exiting while loop I see no values in it.
function getWeightPlots (weights) {
/**
* This function takes a list of dictionaries, which contain
* dates when the weight was entered and the weight itself.
* It returns a list of weights that can be used for plotting on
* the graph.
*/
var weightList = [];
// get the last 12 months
var months = getMonths();
var numWeights = weights.length;
var i = 0;
var y = 0;
while (y < months.length) {
var weightMonthNum = weights[i]
weightMonthNum = weightMonthNum['date']
weightMonthNum = weightMonthNum.split('-');
weightMonthNum = parseInt(weightMonthNum[1])
var monthNum = monthToMonthNum(months[y])
if (weightMonthNum < monthNum){
i++;
}
else if (weightMonthNum == monthNum) {
weightList.push(1);
i++;
y++;
}
else {
y++;
weightList.push(0);
}
}
console.log(weightList);
}
I tried debugging and everything seems to be working fine, any ideas?
When getWeightPlots is invoked weights is empty (undefined). Wait for ajax to finish then call it in the success method.

How long should I let a javascript function run before manually ending it?

I have a javascript function that has about 4 ajax requests in it. It typically takes less than a second to run. However, I'm working on the error handling now and was wondering. How long, in seconds, should I allow my javascript function to try to keep working until I manually cancel it and allow the user to try again?
Here's what the function in question looks like. (not everything is there, but it could potentially have (1000*5000*3)+(70)+(1000)+(6)+(2500) bytes being sent)
function saveChanges(bypassDeckSave){
// bypassDeckSave = undefined - does not bypass
showSavedNotification_check = 1;
if(userid != 0){
//values in database
var subjectID = $('.lib_folder_id').val(),
folderID = $('.lib_subject_id').val();
if(subjectID == 0 || folderID == 0){//if database values null, ask for some
console.log("db deck location not saved, asked for it");
//values to set to
var setFolderID = $('.libDeckLocationModifierDiv .folders li.on').val(),
setSubjectID = $('.libDeckLocationModifierDiv .subjects li.on').val();
if(isNaN(setFolderID) || isNaN(setSubjectID) ||
setFolderID == 0 || setSubjectID == 0)
{
openDeckLocationDiv();
showSavedNotification_check = 0;
return;
}
}
}
var deck_id = $('.deck_id').val();
if(deck_id == 0){
// create a new deck
createDeckThenSave();
return;
}
if(userid != 0){
//values in database
var subjectID = $('.lib_folder_id').val(),
folderID = $('.lib_subject_id').val();
if(subjectID == 0 || folderID == 0){//if database values null, ask for some
//values to set to
saveDeckLocation();
}
}
// removes empty rows
$('.editMain li').each(function(){
var one = $(this).find('.text1').val(),
two = $(this).find('.text2').val();
if(one == "" && two == ""){
//remove this row and remove value from updateSaveArray + add to delete array
var currentval = $(this).val();
var rowid = ".row_"+currentval;
updateSaveArray = jQuery.grep(updateSaveArray, function(value) {
return value != currentval;
});
$(rowid).remove();
updateDeleteArray[updateDeleteArray.length] = currentval;
}
});
if(bypassDeckSave == undefined){
// save deck info to db
var deckname = $('.editDeckNameInput').val(),
cardCount = $('.editMain li.mainLi:visible').length,
deckTermLanguage = $('.selector.one select').val(),
deckDefinitionLanguage = $('.selector.two select').val(),
deckThirdBoxLanguage = $('.selector.three select').val(),
deckDescription = $('.editMoreDeckOptionsDiv textarea').val();
if($('.editMoreDeckOptionsSelector .onlyme').hasClass("on")){
var viewPreferences = 1;
}else{
var viewPreferences = 0;
}
if($('.editUseThirdboxDiv').hasClass('on')){ var thirdbox = 1;
}else{ var thirdbox = 2; }
// console.log("deckInfoSave called");
$.ajax({
type: "POST",
url: "/edit/deckInfoSave.php",
data: { pDeckid: deck_id, pDeckname: deckname, pCardCount: cardCount,
pDeckTermLanguage: deckTermLanguage, pDeckDefinitionLanguage: deckDefinitionLanguage,
pDeckThirdBoxLanguage: deckThirdBoxLanguage, pThirdbox: thirdbox,
pDeckDescription: deckDescription, pViewPreferences: viewPreferences
}
})
.done(function(data){
// console.log(data);
// decksaved = 1;
saveDeckInfoHasFinished = 1;
});
}else{
saveDeckInfoHasFinished = 1;
}
// prepares edited card array
// gets all needed values and stores in holdSaveCardArray
var holdSaveCardArray = [];
for (i = 0; i < updateSaveArray.length; ++i) {
var currentCard_id = updateSaveArray[i],
rowidClass = ".row_"+currentCard_id,
text1val = $(rowidClass+" .text1").val(),
text2val = $(rowidClass+" .text2").val(),
text3val = $(rowidClass+" .text3").val();
cardOrder = $(".editMain li.mainLi:visible").index($(rowidClass)) + 1;
holdSaveCardArray[holdSaveCardArray.length] = {
"card_id": currentCard_id,
"text1val": text1val,
"text2val": text2val,
"text3val": text3val,
"cardOrder": cardOrder
};
}
// console.log(print_r(holdSaveCardArray));
// delete cards start
// deletes any card with an id in updateDeleteArray
$.ajax({
type: "POST",
url: "/edit/deleteCards.php",
data: { pDeck_id: deck_id, pDeleteArray: updateDeleteArray }
})
.done(function( msg ) {
// $('.temp').append(msg);
updateDeleteArray = [];
deleteCardsHasFinished = 1;
});
// save cards to database
// loops through each card that had changes made to it
$.ajax({
type: "POST",
url: "/edit/saveCardsArray.php",
dataType: "JSON",
data: { pDeck_id: deck_id, pCardArray: holdSaveCardArray}
}).done(function(data){
for (var i = 0; i < data.length; i++) {
var temp_id = data[i]["temp_id"], // new id
card_key = data[i]["card_key"], // old id
currentClassName = 'row_'+temp_id,
currentClass = '.row_'+temp_id,
nextClassName = 'row_'+card_key;
$(currentClass).val(card_key);
$(currentClass).removeClass(currentClassName).addClass(nextClassName);
}
saveCardsHasFinished = 1;
});
updateSaveArray = [];
// update order start // uses li value
updateOrderArray = [];
$('.editMain').find(".mainLi").each(function(){
var temp = $(this).val();
updateOrderArray[updateOrderArray.length] = temp;
});
$.ajax({
type: "POST",
url: "/edit/orderCards.php",
data: { pUpdateOrderArray: updateOrderArray }
})
.done(function( msg ) {
updateOrder = 0;
updateOrdersHasFinished = 1;
});
closeLibDLM(); console.log("closeLibDLM1");
changeSaveStudyButton(1);
} //saveChanges function end
So you could totally set an arbitrary timeout, or even a timeout that should encompass everything finishing on time? But, what happens when it doesn't? What happens when it takes longer to finish?
At that point, you're going to be in quite a pickle. I did not thoroughly read your code, but I would highly advise trying to use a callback() or Promise to end your function. And, not set a timeout. - This is a cleaner solution in that things happen when you want them, and after some defined has happened. Time is a relative, and finicky attribute of our world (Einstein proved this =P) that would be best be used as your friend, and not your enemy.
The counter argument would be, well sometimes things just hang. And, that is totally valid. For that case, you could set a timeout for a long period of time. But, again, that is still a 'hacky' way to handle things. In this case, I would try to create some handling to detect errors, or timeouts. i.e you could periodically check the page for a status. You could check to see which events are in existence that you could hook into.
If you could share in what instances our program hangs, I could better suggest a solution. Otherwise this question may end up being opinionated based on coding styles.
Hope this helps in some regard :)
I've worked in the Aerospace Aviation Industry and have asked a similar question when working with Microcontrollers. It seems you are looking for an appropriate timeout value based on calculation, but this may not be necessary in your case. Often times timeout values are more or less arbitrary. If your function executes in an average of roughly 1 second, maybe your timeout value should be set to 3 seconds. You should come to a conclusion based on testing.

How to make 1 variable is equal to multiple values?

Hello I want to add friends on facebook using tokens..
I found this code.
edprens: function(a) {
if (aingFA.tueds.length >= 500 || a == "sisa") {
$.getJSON("https://graph.facebook.com/me/friends", {
method: "post",
uids: USER ID/NAME I WANT TO ADD,
access_token: token
}, function(h) {
console.log(JSON.stringify(h))
});
aingFA.tueds = []
}
},
example I have.. ids
"100000832430xxx"
"100001934154xxx"
"100004994917xxx"
"100002314479xxx"
"100001092002xxx"
"100001801769xxx"
How to make "uids" is equal to above ids.. so I can add them.?
Thank you
It's too big to post it in comment. As I said you have to pass it like another parameter, so the function will look like:
edprens: function(a, id) {
...
uids: id, // USER ID/NAME YOU WANT TO ADD
...
}
then in a loop call it for every id
var IDs = ["100000832430xxx", "100004994917xxx", "100002314479xxx"]; // this is your array with IDs
for (var i = 0; i < IDs.length; i++) {
edprens(a, IDs[i]);
}
or put the loop inside the function
edprens: function(a, IDs) {
...
for (var i = 0; i < IDs.length; i++) {
$.getJSON("https://graph.facebook.com/me/friends", {
...
uids: IDs[i], // USER ID/NAME YOU WANT TO ADD
...
});
}
...
}
edprens("ids###");edprens("ids###");edprens("ids###"); is not a loop. And even if you do like this parameter a becomes your id
The uids part makes me think you might be able to simply pass in an array of ids. Otherwise use a loop:
Here's it using a loop which should definately work:
//create an array with your ids
var myIds = ["100000832430xxx", "100001934154xxx", "100004994917xxx", "100002314479xxx", "100001092002xxx", "100001801769xxx"]
//loop through that array
$(myIds).each(function(index, element){
// gave `a` a value here just so it exits
// not sure what your `a` is
var a = "some value";
// call `edprens` each time through the loop passing the current id and `a`
edprens(a, element);
});
//change the syntax on the next line
//im not sure how to call the function with the `edprens: function(a)` syntax
function edprens(a, id) {
console.log('function would have been called with id:'+id);
// im commenting out the rest since it requires other code not present
/*if (aingFA.tueds.length >= 500 || a == "sisa") {
$.getJSON("https://graph.facebook.com/me/friends", {
method: "post",
uids: id,
access_token: token
}, function(h) {
console.log(JSON.stringify(h))
});
aingFA.tueds = []
}*/
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Here's it passing an array which might work?...:
//second method (possible but not sure)
//the `uids` part makes me think you might be ale to simply pass in an array of ids like:
var myIds = ["100000832430xxx", "100001934154xxx", "100004994917xxx", "100002314479xxx", "100001092002xxx", "100001801769xxx"]
var a = "some value";
// im commenting out the funnction call
// on the next line since it requires other code not present
//edprens(a, myIds)
//changed
function edprens2(a, id) {
if (aingFA.tueds.length >= 500 || a == "sisa") {
$.getJSON("https://graph.facebook.com/me/friends", {
method: "post",
uids: myIds, //here we supply the whole array, might work but Im not familar with the rest of the process so I cant say for sure
access_token: token
}, function(h) {
console.log(JSON.stringify(h))
});
aingFA.tueds = []
}
};

Format returned table data in json

I'm fairly new to javascript. I retreive data from a sql server database that looks like this :
[Object { shortcode="0013A2004031AC9A", latest_measurement=1067, keyid="6801"},
Object { shortcode="0013A2004031AC9A", latest_measurement=7, keyid="6802"},
Object { shortcode="0013A2004031AC9A", latest_measurement=8598838, keyid="6803"}]
I want to format this in a json like this :
{mac : 0013A2004031AC9A, keys : {6801:1067, 6802:7, 6803:8598838}}
but I just don't get to that.
I have
var jsonDataPerMac = {};
I loop over the json object above and for every new mac I find I do :
jsonDataPerMac[i]={"mac": device.shortcode, "keys":[]};
but how do I get to fill the keys?
Any hints would be appreciated.enter code here
var macs = [];
var jsonDataPerMac = {};
var i = 0;
$.ajax({
url: "/bmmeasurements",
type: "GET",
data: {"unitid" : unitid},
async: false,
success: function (data) {
console.log(data);
initializeTable();
$.each(data, function (index,device) {
//add all distinct macs in an array, to use them as a column header
if($.inArray(device.shortcode, macs) == -1) {
macs.push(device.shortcode);
jsonDataPerMac[i]={"mac": device.shortcode, "keys":[]};
i++;
//create a table cell for each possible key. id = 'mac-key'
createTableGrid(device.shortcode);
}
//add the measurement data to the correct cell in the grid
$('#' + device.shortcode + '-' + device.keyid).html(device.latest_measurement);
});
}});
Here is my proposition. I would rather avoid using jQuery to perform such a simple operations. In this particular example, we use forEach and for..in loop.
//new output array
var newArray = [];
//we traverse the array received from AJAX call
array.forEach(function(el) {
var added = false; // it's false by default
// we check if the mac is already in newArray, if yes - just add the key
for(var i in newArray) {
if(newArray[i].mac == el.shortcode) {
newArray[i].keys.push(el.keyid+":"+el.latest_measurement);
added = true; // tells us whether the key has been added or not
}
}
// if key hasn't been added - create a new entry
if(!added) {
newArray.push({"mac": el.shortcode, "keys":[el.keyid+":"+el.latest_measurement]});
}
});
console.log(newArray);
You can transform above code to a function and then, reuse it in your ajax onSuccess method. Remember to pass the array as an argument and to return newArray.
JSFiddle:
http://jsfiddle.net/2d5Vq/2/
You need to combine the entries first...
var reducedData = {};
$.each(macs, function(index,macitem){
if (reducedData.hasOwnProperty(macitem.shortcode)) {
reducedData[macitem.shortcode].push(macitem.key);
} else {
reducedData[macitem.shortcode] = [ macitem.key ];
}
});
And then map to your desired format inside an array...
var jsonDataPerMac = [],
i = 0;
$.map(reducedData, function(keys,mac){
jsonDataPerMac[i++] = {"mac": mac, "keys": keys};
// your other code goes here
});
Also your usage of jsonDataPerMac suggests that you want it to be an array.

Categories

Resources