Node.js / Javascript - Wait until method is finished - javascript

I'm writing a steam trade bot but I have the problem that the for-loop doesn't wait until the method which is inside the for-loop is finished. So the code doesn't work as it should.
for (i = 0; i < offer.itemsToReceive.length; i++) {
console.log(offer.itemsToReceive[i].market_hash_name);
community.getMarketItem(appid.CSGO, offer.itemsToReceive[i].market_hash_name, function(err, items) {
if (err) {
Winston.error("Error getting Marketprice");
} else {
var cacheItemPrice = items.lowestPrice;
totalValue += items.lowestPrice;
Winston.info("Item " + offer.itemsToReceive[i].market_hash_name + " is " + items.lowestPrice + " Cents worth");
if (items.lowestPrice <= minValue) {
minValue = items.lowestPrice;
}
}
});
}
If the loop doesn't wait until the method is finished, the variable i isn't correct in the method and I get a wrong result.
Edit:
Now when I put the code from #Cleiton into my function from which I want to return two values, the function returns the value before the method has time to change the them.
function checkItemPricesCashIn(offer) {
Winston.info("Getting itemprices from trade #" + offer.id);
var totalValue = 0;
var minValue = 50;
var executionList = [];
function getMarketItem(item) {
var market_hash_name = item.market_hash_name;
return function() {
community.getMarketItem(appid.CSGO, market_hash_name, function(err, items) {
if (err) {
Winston.error("Error getting Marketprice");
} else {
var cacheItemPrice = items.lowestPrice;
totalValue += items.lowestPrice;
Winston.info("Item " + market_hash_name + " is " + items.lowestPrice + " Cents worth");
if (items.lowestPrice <= minValue) {
minValue = items.lowestPrice;
}
}
(executionList.shift() || function() {})();
});
}
}
offer.itemsToReceive.forEach(function(item) {
executionList.push(getMarketItem(item));
});
if (executionList.length) {
executionList.shift()();
}
console.log(totalValue);
console.log(minValue);
return {
totalValue: totalValue,
minValue: minValue
}
}

Below is a complete working code, I hope this helps :)
function checkItemPricesCashIn(offer, cb) {
Winston.info("Getting itemprices from trade #" + offer.id);
var totalValue = 0;
var minValue = 50;
var executionList = [];
function getMarketItem(item) {
var market_hash_name = item.market_hash_name;
return function() {
community.getMarketItem(appid.CSGO, market_hash_name, function(err, items) {
if (err) {
Winston.error("Error getting Marketprice");
} else {
var cacheItemPrice = items.lowestPrice;
totalValue += items.lowestPrice;
Winston.info("Item " + market_hash_name + " is " + items.lowestPrice + " Cents worth");
if (items.lowestPrice <= minValue) {
minValue = items.lowestPrice;
}
}
(executionList.shift() || cb)(minValue,totalValue);
});
}
}
offer.itemsToReceive.forEach(function(item) {
executionList.push(getMarketItem(item));
});
if (executionList.length) {
executionList.shift()();
}
}
How to use:
checkItemPricesCashIn(yourOffer/*your offer*/, function(min, max){
//it will be execute just after
console.log('min', min);
console.log('max', max);
});

You could use some library as async https://github.com/caolan/async. And with it any async cycle as eachSeries or just each.
async.each(array, function(item, callback){
// do something with a item
// call callback when finished
callback();
});

Related

Blogger random post display to prevent no posts infinite loop

How can I get Blogger to display random posts, while preventing an infinite loop when there are no posts to display?
Here is my JavaScript code which I am attempting to use:
<script>
var dt_numposts = 10;
var dt_snippet_length = 100;
var dt_info = 'true';
var dt_comment = 'Comment';
var dt_disable = '';
var dt_current = [];
var dt_total_posts = 0;
var dt_current = new Array(dt_numposts);
function totalposts(json) {
dt_total_posts = json.feed.openSearch$totalResults.$t
}
document.write('<script type=\"text/javascript\" src=\"/feeds/posts/summary?max-results=100&orderby=published&alt=json-in-script&callback=totalposts\"><\/script>');
function getvalue() {
for (var i = 0; i < dt_numposts; i++) {
var found = false;
var rndValue = get_random();
for (var j = 0; j < dt_current.length; j++) {
if (dt_current[j] == rndValue) {
found = true;
break
}
};
if (found) {
i--
} else {
dt_current[i] = rndValue
}
}
};
function get_random() {
var ranNum = 1 + Math.round(Math.random() * (dt_total_posts - 1));
return ranNum
};
function random_list(json) {
a = location.href;
y = a.indexOf('?m=0');
for (var i = 0; i < dt_numposts; i++) {
var entry = json.feed.entry[i];
var dt_posttitle = entry.title.$t;
if ('content' in entry) {
var dt_get_snippet = entry.content.$t
} else {
if ('summary' in entry) {
var dt_get_snippet = entry.summary.$t
} else {
var dt_get_snippet = "";
}
};
dt_get_snippet = dt_get_snippet.replace(/<[^>]*>/g, "");
if (dt_get_snippet.length < dt_snippet_length) {
var dt_snippet = dt_get_snippet
} else {
dt_get_snippet = dt_get_snippet.substring(0, dt_snippet_length);
var space = dt_get_snippet.lastIndexOf(" ");
dt_snippet = dt_get_snippet.substring(0, space) + "…";
};
for (var j = 0; j < entry.link.length; j++) {
if ('thr$total' in entry) {
var dt_commentsNum = entry.thr$total.$t + ' ' + dt_comment
} else {
dt_commentsNum = dt_disable
};
if (entry.link[j].rel == 'alternate') {
var dt_posturl = entry.link[j].href;
if (y != -1) {
dt_posturl = dt_posturl + '?m=0'
}
var dt_postdate = entry.published.$t;
if ('media$thumbnail' in entry) {
var dt_thumb = entry.media$thumbnail.url
} else {
dt_thumb = "https://blogspot.com/"
}
}
};
document.write('<img alt="' + dt_posttitle + '" src="' + dt_thumb + '"/>');
document.write('<div>' + dt_posttitle + '</div>');
if (dt_info == 'true') {
document.write('<span>' + dt_postdate.substring(8, 10) + '/' + dt_postdate.substring(5, 7) + '/' + dt_postdate.substring(0, 4) + ' - ' + dt_commentsNum) + '</span>'
}
document.write('<div style="clear:both"></div>')
}
};
getvalue();
for (var i = 0; i < dt_numposts; i++) {
document.write('<script type=\"text/javascript\" src=\"/feeds/posts/summary?alt=json-in-script&start-index=' + dt_current[i] + '&max-results=1&callback=random_list\"><\/script>')
};
</script>
Expected output:
?
Actual output:
?
It looks like your post is mostly code; please add some more details.
It looks like you're trying to populate dt_current with dt_numposts = 10 elements. I modified getvalue() as follows, so that dt_numposts is capped at dt_total_posts, which may be 0. This allows the outer for loop to exit.
function getvalue() {
dt_numposts = (dt_total_posts < dt_numposts) ? dt_total_posts : dt_numposts;
// ...
I couldn't test this, because I don't have an example /feeds/posts/summary?max-results=100&orderby=published&alt=json-in-script&callback=totalposts JSON resource, but it works for zero posts. Whether is works for dt_numposts > 0, you'll need to test!

Recursive java script function - out of control

The code below works. The code calls an API to get historical trades (100 trades each time pér pull). Because there is an limit - how many and how often im allowed to call the API - the structure is like recursive.
The flow is like this:
Get the current MAX tradeId - which is stored in the DB.
Now make a new PULL with startIndex = MaxId and a length of 100 (to pull 100 new trades).
FIRST when the callback function is called the main code continues and 100 new trades are pulled... ect. ect.
So...
The code SHOULD behave like - Psydo-code
var maxId = GetMaxIdFromDB();
Pull(maxId, 100, callback);
function callback(){
... do different stuff..
maxId += 100;
Pull(maxId, 100, callback);
}
The strange thing and my question is: How can the API function "getProductTrades " be called more than one time - where my cursor variable contains the SAME value - when it is incremented with 100 (or the number of valid data elements each time).
I'm talking/ref. especially to the following lines:
wl.debug("getProductTrades - cursor: " + cursor + " Limit: " + limit);
publicClient.getProductTrades({'after': cursor, 'limit': limit}, callback);
The insertQuery.InsertMatchMsgArrayToDB(allData); method calls another DB method which returns a promise.
You can see a screenshot of the issue here:
http://screencast.com/t/DH8rz3UxnyZ
The real code is here:
pullTradesBetween: function (minTradeId, maxTradeId) {
var wl = new WinLog();
var tradeCounter = 0;
try {
var WebSocketEmit = new WSemitter();
var startTime = new Date().toLocaleString();
var executeTradePullAgain = null;
wl.debug("REST API START: " + startTime);
var cursor;
var incrementedCursorWith = 0;
if ((maxTradeId - minTradeId) < 100) {
cursor = maxTradeId + 1;
}
else
cursor = minTradeId + 100;
var callback = function (err, response, data) {
if (executeTradePullAgain !== null)
clearTimeout(executeTradePullAgain);
if (err)
wl.info("Err: " + err);
var validData = [];
incrementedCursorWith = 0;
if (response == null)
wl.info("RESPONSE ER NULL");
if (data !== null) {
for (var i = data.length - 1; i >= 0; i--) {
var obj = data[i];
var tradeId = parseInt(obj.trade_id);
if (obj !== null && (minTradeId <= tradeId && tradeId <= maxTradeId)) {
validData.push(data[i]);
}
}
if (validData.length == 0) {
wl.debug("Contains 0 elements!");
}
else {
cursor = cursor + validData.length;
incrementedCursorWith = validData.length;
insertDataToDB(validData);
}
}
else
wl.debug("DATA IS NULL!");
wl.debug("cursor: " + cursor + " maxTradeId: " + maxTradeId);
var diffToMax = maxTradeId - (cursor - incrementedCursorWith);
if (diffToMax >= 100)
pullTrades(cursor, 100); // 100 is default
else if (diffToMax >= 0)
pullTrades(maxTradeId + 1, diffToMax + 1); // X = Only the last trades in the given series of trades
else {
wl.info("REST API START: " + startTime + " REST API DONE: " + new Date().toLocaleString());
WebSocketEmit.syncHistoricalDataDone();
}
};
function pullTrades(cursor, limit) {
tradeCounter += limit;
if(tradeCounter % 10000 == 0){
wl.info('Downloaded: ' + tradeCounter + ' trades via REST API (Total: ' + cursor + ')');
}
pullTradesAgainIfServerDoesNotRespond(cursor, limit);
wl.debug("getProductTrades - cursor: " + cursor + " Limit: " + limit);
publicClient.getProductTrades({'after': cursor, 'limit': limit}, callback);
}
function pullTradesAgainIfServerDoesNotRespond(cursor, limit) {
executeTradePullAgain = setTimeout(function () {
wl.debug('pullTradesAgainIfServerDoesNotRespond called!');
pullTrades(cursor, limit);
}, 30000);
}
// SAVE DATA IN DB!
function insertDataToDB(allData) {
insertQuery.InsertMatchMsgArrayToDB(allData);
}
wl.debug("pull trades: " + cursor);
pullTrades(cursor, 100);
}
catch(err){
wl.info('pullTradesBetween: ' + err);
} }};
It happens when you get no data out of getProductionTrades.
If the data returned is null, you will never reach the lines
cursor = cursor + validData.length;
incrementedCursorWith = validData.length;
but you still call
pullTrades(cursor, 100);
at the end. I don't know if it's intended or an actual error so i leave the solution (should be trivial now) up to you.
I try to simplify your code
pullTradesBetween: function (minTradeId, maxTradeId) {
var WebSocketEmit = new WSemitter(); // try-catch ?
var curr = (maxTradeId - minTradeId < 100) ? maxTradeId + 1 : minTradeId + 100;
// function always return data or infinite error-loop
function getProductTrades (after, limit, callback) {
// try-catch ?
publicClient.getProductTrades ({after, limit}, function(err, data) {
if (err) {
console.log(err);
return getTrades(after, limit, callback);
}
callback(null, data);
});
}
function onDataReady (err, data) {
if (err)
throw new Error('Impossible!');
if (!data || !(data instanceof Array))
return ... smth on empty data ...
var validData = data.filter(function(obj) {
return obj &&
minTradeId <= parseInt(obj.trade_id) &&
parseInt(obj.trade_id) <= maxTradeId;
}).reverse();
if (validData.length == 0)
return ... smth on empty data ...
insertDataToDB(validData);
curr += validData.length; // maybe +-1
var remaining = maxTradeId - curr;
if (remainig == 0) {
console.log('Done');
// try-catch ?
WebSocketEmit.syncHistoricalDataDone();
}
return (remaining >= 100) ?
getProductTrades(curr, 100, onDataReady) :
getProductTrades(maxTradeId + 1, remaining + 1, onDataReady); // ??
}
getProductTrades(curr, 100, onDataReady);
}

azure asynchronous javascript backend - wait function

I'm using Azure Mobile Services and a javascript backend. My problem is that the function don't wait the end of an other function.
I'm trying to choose an item (word) with a particolar rules. i want to pick the item with highest item.wordnumber. If there are few item with the same item.wordnumber i want to pick who has a highest avarage of votes associated at that item (in the other table "votes").
This script don't wait the return of function CalcolateMaxAvg.
I would do as I did in c # with await.
var tableWords = tables.getTable('Word');
var tableVotes = tables.getTable('Votes');
var avgVotesActualWord = 0;
var maxItem = null;
var maxItemVote = 0;
function WordChoice() {
var select = tableWords.orderByDescending('wordnumber').read({success:
function (results)
{
results.forEach(function(item)
{
if(maxItem == null)
{
maxItem = item;
maxItemVote = tableVotes.where({idword: item.id}).read({success: CalcolateMaxAvg});
}
else if(item.wordnumber > maxItem.wordnumber)
{
maxItem = item;
maxItemVote = tableVotes.where({idword: item.id}).read({success: CalcolateMaxAvg});
}
else if(item.wordnumber == maxItem.wordnumber)
{
//chack who have more votes
avgVotesActualWord = 0;
avgVotesActualWord = tableVotes.where({idword: item.id}).read({success: CalcolateMaxAvg});
//the problem is avgVoteActualWord that is always NaN
console.log('Word: %s with avg: %d', item.word, avgVotesActualWord);
if(avgVotesActualWord > maxItemVote)
{
//take the actualword because have more votes
maxItem = item;
maxItemVote = avgVotesActualWord;
}
}
})
if(maxItem != null)
{
console.log('parola: %s', maxItem.word);
maxItem.selected = true;
tableWords.update(maxItem);
}
else
{
console.log('null');
}
}
});
}
function CalcolateMaxAvg(resultsVote)
{
var sum = 0;
var count = 0;
var avg = 0;
resultsVote.forEach(function(itemVote)
{
sum = sum + itemVote.vote;
count = count + 1;
})
if(count > 0)
{
avg = sum / count;
}
//this is a correct value of avgVoteActualWord, but he don't wait the return of this value
console.log('avg: %d', avg);
return avg;
}
The problem is that a call to table.where(...).read(...) is asynchronous - it won't return a number returned by the CalcolateMaxAvg function (it won't return anything). You need to rewrite your code to embrace the asynchronicity of JavaScript, something along the lines of the code below.
var tableWords = tables.getTable('Word');
var tableVotes = tables.getTable('Votes');
var avgVotesActualWord = 0;
var maxItem = null;
var maxItemVote = 0;
function WordChoice() {
var select = tableWords.orderByDescending('wordnumber').read({
success: function (results)
{
function processNextResult(index) {
if (index >= results.length) {
// All done
if(maxItem != null)
{
console.log('parola: %s', maxItem.word);
maxItem.selected = true;
tableWords.update(maxItem);
}
else
{
console.log('null');
}
return;
}
var item = results[index];
if (maxItem == null) {
maxItem = item;
tableVotes.where({ idword: item.id }).read({ success: simpleProcessVotesResult });
} else if (item.wordnumber > maxItem.wordnumber) {
maxItem = item;
tableVotes.where({ idword: item.id }).read({ success: simpleProcessVotesResult });
} else if (item.wordnumber == maxItem.wordnumber) {
//check who have more votes
avgVotesActualWord = 0;
tableVotes.where({idword: item.id}).read({
success: function(resultsVote) {
avgVotesActualWord = CalcolateMaxAvg(resultsVote);
//the problem is avgVoteActualWord that is always NaN
console.log('Word: %s with avg: %d', item.word, avgVotesActualWord);
if(avgVotesActualWord > maxItemVote)
{
//take the actualword because have more votes
maxItem = item;
maxItemVote = avgVotesActualWord;
}
processNextResult(index + 1);
}
});
} else {
processNextResult(intex + 1);
}
}
function simpleProcessVotesResult(resultsVote) {
maxItemsVote = CalcolateMaxAvg(resultsVote);
processNextResult(intex + 1);
}
processNextResult(0);
}
});
}
function CalcolateMaxAvg(resultsVote)
{
var sum = 0;
var count = 0;
var avg = 0;
resultsVote.forEach(function(itemVote)
{
sum = sum + itemVote.vote;
count = count + 1;
})
if(count > 0)
{
avg = sum / count;
}
//this is a correct value of avgVoteActualWord, but he don't wait the return of this value
console.log('avg: %d', avg);
return avg;
}

chrome Event is not dispatched

I'm having a little problem. I thought I had understood Event Handling, but now I don't think so anymore.
I've created a Chrome Event():
this.onReadLine = new chrome.Event();
this event is dispatched in a function:
this.onReadLine.dispatch(line);
before the dispatch instruction I've tried to log 'line', the argument of the dispatch instruction. No problem, 'line' exists.
Going straight down with the code you will find this part:
connection.onReadLine.addListener(function(line) {
logJSON(line);
});
this is what must be fired every time the onReadLine event is dispatched.
The problem is that the Event onReadLine is only dispatched when I push or release the button '#dimmer1_Chrome_Input' defined at the end of my code.
Where I'm wrong?
My full code here. The parts related to problem are highlighted with ////\///\/\///\\ lines.
// Serial used from Arduino board
const Arduino_COM = 'COM3'; // PC
var SerialConnection = function() {
this.connectionId = -1;
this.lineBuffer = "";
this.boundOnDataReceiving = this.onDataReceiving.bind(this);
this.boundOnDataReceivingError = this.onDataReceivingError.bind(this);
this.onConnect = new chrome.Event();
///////////////////////////\\\\\\\\\\\\\\\/////////////\\\\\\\\\\////////\\\\\\\\\\\\////////\\\\\\\\\\//////PROBLEM
this.onReadLine = new chrome.Event();
///////////////////////////\\\\\\\\\\\\\\\/////////////\\\\\\\\\\////////\\\\\\\\\\\\////////\\\\\\\\\\//////PROBLEM
this.onError = new chrome.Event();
};
SerialConnection.prototype.connect = function(Serial_COM_Port) {
chrome.serial.connect(Serial_COM_Port, this.onConnectComplete.bind(this));
};
SerialConnection.prototype.onConnectComplete = function(connectionInfo) {
if (!connectionInfo) {
log("Connection failed.");
return;
}
this.connectionId = connectionInfo.connectionId;
chrome.serial.onReceive.addListener(this.boundOnDataReceiving);
chrome.serial.onReceiveError.addListener(this.boundOnDataReceivingError);
this.onConnect.dispatch();
};
SerialConnection.prototype.send = function(msg) {
if (this.connectionId < 0) {
throw 'Invalid connection';
}
chrome.serial.send(this.connectionId, String_to_ArrayBuffer(msg), function() {});
};
SerialConnection.prototype.onDataReceiving = function(receiveInfo) {
if (receiveInfo.connectionId !== this.connectionId) {
return;
}
this.lineBuffer += ArrayBuffer_to_String(receiveInfo.data);
var index;
while ((index = this.lineBuffer.indexOf('\n')) >= 0) {
var line = this.lineBuffer.substr(0, index + 1);
console.log(line);
///////////////////////////\\\\\\\\\\\\\\\/////////////\\\\\\\\\\////////\\\\\\\\\\\\////////\\\\\\\\\\//////PROBLEM
this.onReadLine.dispatch(line);
///////////////////////////\\\\\\\\\\\\\\\/////////////\\\\\\\\\\////////\\\\\\\\\\\\////////\\\\\\\\\\//////PROBLEM
this.lineBuffer = this.lineBuffer.substr(index + 1);
}
};
SerialConnection.prototype.onDataReceivingError = function(errorInfo) {
if (errorInfo.connectionId === this.connectionId) {
this.onError.dispatch(errorInfo.error);
}
};
SerialConnection.prototype.disconnect = function() {
if (this.connectionId < 0) {
throw 'Invalid connection';
}
chrome.serial.disconnect(this.connectionId, function() {});
};
var connection = new SerialConnection();
connection.onConnect.addListener(function() {
log('connected to: ' + Arduino_COM);
});
///////////////////////////\\\\\\\\\\\\\\\/////////////\\\\\\\\\\////////\\\\\\\\\\\\////////\\\\\\\\\\//////PROBLEM
connection.onReadLine.addListener(function(line) {
logJSON(line);
});
///////////////////////////\\\\\\\\\\\\\\\/////////////\\\\\\\\\\////////\\\\\\\\\\\\////////\\\\\\\\\\//////PROBLEM
connection.connect(Arduino_COM);
function logJSON(result) {
var response = jQuery.parseJSON( result );
dimmer1_state = response.dimmer1_state;
dimmer1_value = response.dimmer1_value;
SerialIn = response.SerialIn;
dimmer1_Chrome_Input = response.dimmer1_Chrome_Input;
temperature1_value = response.temperature1_value;
s=Math.round(dimmer1_value * 80 / 255 + 20);
hsl='hsl(115,'+s+'%,60%)';
if (dimmer1_state == 0)
{
$('#statusCircle').css('fill','hsl(115,20%,60%)');
}
else
{
$('#statusCircle').css('fill', hsl);
};
// Print led Status to HTML buffer area
messaggio = "dimmer1 state: " + dimmer1_state
+ "<br />dimmer1 value: " + dimmer1_value
+ "<br />SerialIn: " + SerialIn
+ "<br />dimmer1_Chrome_Input: " + dimmer1_Chrome_Input
+ "<br />temperature1_value: " + temperature1_value + " °C";
log(messaggio);
};
function log(msg) {
$('#buffer').html(msg);
};
$(function(){
$('#dimmer1_Chrome_Input') .button()
.mousedown(function() {
connection.send("101");
})
.mouseup(function() {
connection.send("100");
});
});
The code is correct, the error was in another part of program

javascript: How to build a function that refers to the variables in my Quiz app?

I recently built a small quiz application, it currently only has two questions. After all the questions are finished I would like for the app to present a page that says "You made it here" (eventually I'll add more). However for some reason the final-function feedback of this code is not working. Where am I going wrong?
$(document).ready(function () {
var questions = [
{question: "Who is Zack Morris?",
choices: ['images/ACslater.jpg','images/CarltonBanks.jpeg','images/ZachMorris.jpg'],
quesNum: 1,
correctAns: 2},
{question: "Who is Corey Matthews?",
choices: ['images/CoryMatthews.jpeg','images/EdAlonzo.jpg','images/Shawnhunter.jpg'],
quesNum: 2,
correctAns: 1},
];
var userAnswer //THis needs to be looked into
var counter = 0;
var score = 0;
var html_string = '';
var string4end = ''
//function to loop choices in HTML, updates counter, checks answer
var update_html = function(currentQuestion) {
// put current question into a variable for convenience.
// put the question string between paragraph tags
html_string = '<p>' + currentQuestion.question + '</p>';
// create an unordered list for the choices
html_string += '<ul>';
// loop through the choices array
for (var j = 0; j < currentQuestion.choices.length; j++) {
// put the image as a list item
html_string += '<li><img src="' + currentQuestion.choices[j] + '"></li>';
}
html_string += '</ul>';
$('.setImg').html(html_string);
}
update_html(questions[0]);
$('.setImg li').on('click', function (e) {
userAnswer = $(this).index();
checkAnswer();
counter++;
update_html(questions[counter]);
$('#score').html(score);
showFinalFeedback();
});
//function to identify right question
function checkAnswer ()
{
if (userAnswer === questions[counter].correctAns)
{
score=+100;
}
}
function showFinalFeedback ()
{
if (counter === (questions.length+1))
{
string4end = '<p>' + 'You made it here!!!!' + '</p>';
$('.setImg').html(string4end);
}
}
});
I agree with Vector that you either should start with 1 as Counter initialization or, to check
if (counter < questions.length) {
return;
}
alert('You \'ve made it till here');
I also rewrote it in a form of a jquery plugin, maybe a handy comparison to your way of working?
jsfiddle: http://jsfiddle.net/DEb7J/
;(function($) {
function Question(options) {
if (typeof options === 'undefined') {
return;
}
this.chosen = -1;
this.question = options.question;
this.options = options.options;
this.correct = options.correct;
this.toString = function() {
var msg = '<h3><i>' + this.question + '</i></h3>';
for (var i = 0; i < this.options.length; i++) {
msg += '<a id="opt' + i + '" class="answer toggleOff" onclick="$(this.parentNode).data(\'quizMaster\').toggle(' + i + ')">' + this.options[i] + '</a>';
}
return msg;
};
this.toggle = function(i) {
var el = $('#opt' + i);
if ($(el).hasClass('toggleOff')) {
$(el).removeClass('toggleOff');
$(el).addClass('toggleOn');
} else {
$(el).removeClass('toggleOn');
$(el).addClass('toggleOff');
}
};
}
function Quiz(elem, options) {
this.element = $(elem);
this.lastQuestion = -1;
this.questions = [];
this.correct = 0;
if (typeof options !== 'undefined' && typeof options.questions !== undefined) {
for (var i = 0; i < options.questions.length; i++) {
this.questions.push(new Question(options.questions[i]));
}
}
this.start = function() {
this.lastQuestion = -1;
this.element.html('');
for (var i = 0; i < this.questions.length; i++) {
this.questions[i].chosen = -1;
}
this.correct = 0;
this.next();
};
this.next = function() {
if (this.lastQuestion >= 0) {
var p = this.questions[this.lastQuestion];
if (p.chosen === -1) {
alert('Answer the question first!');
return false;
}
if (p.chosen === p.correct) {
this.correct++;
}
$(this.element).html('');
}
this.lastQuestion++;
if (this.lastQuestion < this.questions.length) {
var q = this.questions[this.lastQuestion];
$(this.element).html(q.toString());
console.log(q.toString());
} else {
alert('you replied correct on ' + this.correct + ' out of ' + this.questions.length + ' questions');
this.start();
}
};
this.toggle = function(i) {
if (this.lastQuestion < this.questions.length) {
var q = this.questions[this.lastQuestion];
q.toggle(q.chosen);
q.toggle(i);
q.chosen = i;
}
};
}
$.fn.quizMaster = function(options) {
if (!this.length || typeof this.selector === 'undefined') {
return;
}
var quiz = new Quiz($(this), options);
quiz.start();
$(this).data('quizMaster', quiz);
$('#btnConfirmAnswer').on('click', function(e) {
e.preventDefault();
quiz.next();
});
};
}(jQuery));
$(function() {
$('#millionaire').quizMaster({
questions: [
{
question: 'Where are the everglades?',
options: ['Brazil','France','USA','South Africa'],
correct: 2
},
{
question: 'Witch sport uses the term "Homerun"?',
options: ['Basketball','Baseball','Hockey','American Football'],
correct: 1
}
]
});
});
Hey guys thanks for your help. I was able to use the following work around to ensure everything worked:
$('.setImg').on('click', 'li', function () {
userAnswer = $(this).index();
checkAnswer();
counter++;
$('#score').html(score);
if (counter < questions.length)
{
update_html(questions[counter]);
}
else{
showFinalFeedback();
}
});

Categories

Resources