I’m creating a Facebook game using HTML and Javascript, and I’ve just finished building a leaderboard table which lists every player’s name and rank number. This table is populated with data returned from Facebook's game scores API.
This is working perfectly, but I also want to reward players for improving their rank in the table.
This is how I plan to do this:
- When the game loads, I run a function called
updateTable();
, this populates the leaderboard with the scores and ranks of the players received from an API call to Facebook's database. - When the player starts to play the game, I store a copy of their rank inside a separate hidden div.
- When the game ends, if the player has achieved a new high score, then
it gets entered into the database. After this happens, I run
updateTable();
again to update the leaderboard. - I then run a function called
pareRanks();
, this pares the player’s new rank with the rank that I’ve stored in the hidden div.
If the new ranking is a lower number than the stored rank, then they’ve moved up the leaderboard and I reward them 100 coins for every place they move up.
For example:
Player A starts the game and is ranked 5th (so “5” gets stored in a hidden div). When Player A finishes the game, the leaderboard is updated, and Player A is now ranked 2nd (so the player has jumped 3 places).
To work out what the reward should be, I want to subtract the first variable from the second (5-2 = 3), Player A overtook 3 other players, so their reward will be 3 x 100 gold coins.
The problem I’m having is that when I run pareRanks();
, the new rank keeps showing up as the same number as the stored rank, even though I know that the player has improved their rank.
I’m pretty sure this is due to the new rank being grabbed before updateTable();
has fully interacted with the database. I’ve tested this by separating the functions, by making pareRanks();
run on click of a button, when I did this, I pleted a game, improved my rank, waited a few seconds after updateTable();
ran, then clicked the button, and the two ranks showed up differently, which is correct. So I think pareRanks();
just needs to wait for updateTable();
to fully plete before it runs.
This is how my functions are laid out:
updateTable(){
//code here interacts with the database/makes a call using Facebook's API,
//and populates the leaderboard table with the returned data
}
On start of a new game, the player’s current rank is stored in the hidden div.
When the game pletes updateTable();
is run again, followed by pareRanks();
:
pareRanks(){
//code here grabs the stored rank from the hidden div
//code here grabs the newly updated rank and pares the two.
}
I’ve read answers about using callbacks, but I couldn’t get them to work. And I’ve tried doing something like this:
updateTable(){
{
//code here interacts with the database/makes a call using Facebook's API,
//and populates the leaderboard table with the returned data
}
pareRanks();
};
But the new rank is still showing up the same as the old rank when pareRanks();
runs. updateTable();
is changing the ranks correctly on the leaderboard when it runs, so I think pareRanks();
is just running before updateTable();
fully pletes.
I’d really appreciate any help in fixing this problem, thank you in advance!
I’m creating a Facebook game using HTML and Javascript, and I’ve just finished building a leaderboard table which lists every player’s name and rank number. This table is populated with data returned from Facebook's game scores API.
This is working perfectly, but I also want to reward players for improving their rank in the table.
This is how I plan to do this:
- When the game loads, I run a function called
updateTable();
, this populates the leaderboard with the scores and ranks of the players received from an API call to Facebook's database. - When the player starts to play the game, I store a copy of their rank inside a separate hidden div.
- When the game ends, if the player has achieved a new high score, then
it gets entered into the database. After this happens, I run
updateTable();
again to update the leaderboard. - I then run a function called
pareRanks();
, this pares the player’s new rank with the rank that I’ve stored in the hidden div.
If the new ranking is a lower number than the stored rank, then they’ve moved up the leaderboard and I reward them 100 coins for every place they move up.
For example:
Player A starts the game and is ranked 5th (so “5” gets stored in a hidden div). When Player A finishes the game, the leaderboard is updated, and Player A is now ranked 2nd (so the player has jumped 3 places).
To work out what the reward should be, I want to subtract the first variable from the second (5-2 = 3), Player A overtook 3 other players, so their reward will be 3 x 100 gold coins.
The problem I’m having is that when I run pareRanks();
, the new rank keeps showing up as the same number as the stored rank, even though I know that the player has improved their rank.
I’m pretty sure this is due to the new rank being grabbed before updateTable();
has fully interacted with the database. I’ve tested this by separating the functions, by making pareRanks();
run on click of a button, when I did this, I pleted a game, improved my rank, waited a few seconds after updateTable();
ran, then clicked the button, and the two ranks showed up differently, which is correct. So I think pareRanks();
just needs to wait for updateTable();
to fully plete before it runs.
This is how my functions are laid out:
updateTable(){
//code here interacts with the database/makes a call using Facebook's API,
//and populates the leaderboard table with the returned data
}
On start of a new game, the player’s current rank is stored in the hidden div.
When the game pletes updateTable();
is run again, followed by pareRanks();
:
pareRanks(){
//code here grabs the stored rank from the hidden div
//code here grabs the newly updated rank and pares the two.
}
I’ve read answers about using callbacks, but I couldn’t get them to work. And I’ve tried doing something like this:
updateTable(){
{
//code here interacts with the database/makes a call using Facebook's API,
//and populates the leaderboard table with the returned data
}
pareRanks();
};
But the new rank is still showing up the same as the old rank when pareRanks();
runs. updateTable();
is changing the ranks correctly on the leaderboard when it runs, so I think pareRanks();
is just running before updateTable();
fully pletes.
I’d really appreciate any help in fixing this problem, thank you in advance!
Share Improve this question edited Apr 11, 2016 at 14:10 Emily asked Apr 11, 2016 at 14:05 EmilyEmily 1,1515 gold badges21 silver badges44 bronze badges 1- If you are looking for how to call a function after the previous is plete, check this out: stackoverflow./questions/5000415/… – aless80 Commented Apr 11, 2016 at 14:11
4 Answers
Reset to default 4A good way of approaching this would be the use of Javascript Promises. They allow you to do async stuff without nesting multiple callback functions.
function first (parameter){
return new Promise(function(resolve,reject){
//Do async stuff, maybe some ajax
//When async stuff is finished:
resolve(async_data);
//Or when something went wrong:
reject(error);
}
}
function second(parameter){
return new Promise(function(resolve,reject){
//Do async stuff, maybe some ajax
//When async stuff is finished:
resolve(async_data);
//Or when something went wrong:
reject(error);
}
}
//You can then use:
first(data).then(second(async_data)).then(function(async_data){
//Here would be the point where both functions finished after eachother!
}).catch(function(error){
//Hey, one of my promises was rejected! Maybe I should handle that error :)
});
This es with a few advantages. You can put as many functions and operations as you want into that chain of .then
s without nesting big amounts of callback functions. You can also access the reject()
call by using .catch()
. You should concider reading the docs for Promises as there are many more features that should be interesting for you.
If you don't want to get involved with Promises (They make your code alot cleaner because they're posable so you can create very clear chains of promises) you can look into some of the other awnsers that work with Callbacks (Not that bad for such a small usecase).
Here is a great article about it: Article: JavaScript Promises
Basically a callback is a function passed in as a parameter to another function. JavaScript can do this because functions are first-class objects.
Now, because updateTable
will call a db/FB API, you need to invoke the callback within the callback for that operation. I don't know the correct syntax for that operation, so my example uses pseudocode.
function updateTable(callback) {
FBAPI.get(something, function (data) {
// do things
callback();
});
}
updateTable(pareRanks);
Note, if pareRanks
needs access to the data from the API you would pass in the data to the callback too:
callback(data);
Better go with new Promise
object of javascript-
The Promise object is used for deferred and asynchronous putations. A Promise represents an operation that hasn't pleted yet, but is expected in the future.
new Promise(executor);
new Promise(function(resolve, reject) { ... });
Check this link for more help- https://developer.mozilla/en/docs/Web/JavaScript/Reference/Global_Objects/Promise
The ment from Aless80 holds the key to your answer I think. I don't know how the Facebook API looks like, but whenever you interact with a database or web-server like that it is mon for the API call to have a callback in which you can handle anything the server might return to you.
For instance, a simple web-server I am working on handles requests send via AJAX calls from a browser. I am using Jquery to do this, but the structure should be roughly the same.
var dataObject = {};
var dataID = "1234";
$.ajax({
type: "GET", // basic http get request
url: "http://www.mywebserver./get-data/" + dataID,
crossDomain: true
}).done(function(response){
// this function runs after the webserver has received our GET request and handled it
// response contains the data we got back from mywebserver
dataObject = response;
});
DoSomething(dataObject);
What happens here is that "DoSomething()" will fire before the dataObject contains any data returned by the database! So if we want to do something with the returned data we should call the function in the "callback" of our ajax request, like so:
var dataObject = {};
var dataID = "1234";
$.ajax({
type: "GET", // basic http get request
url: "http://www.mywebserver./get-data/" + dataID,
crossDomain: true
}).done(function(response){
//dataObject = response;
//DoSomething(dataObject);
DoSomething(response);
});
The mented out stuff in this example is for clarity, of course needlessly passing around variables is something we'd like to avoid :)
I also highly remend looking into JavaScript callbacks. They are tricky to grasp at first but Node.js is basically build upon the concept so it is well worth being familiar with them.