Reputation: 37
I'm trying to make a RuneScape hiscores checker in Meteor.js. I'm now successfully parsing data from their API and saving it as object (you can see app in action here: http://rs-hiscores.meteor.com/). Here's my server code:
var cheerio = Meteor.npmRequire('cheerio');
var BASE_SKILLS = [
'overall', 'attack', 'defence', 'strength', 'hitpoints', 'ranged',
'prayer', 'magic', 'cooking', 'woodcutting', 'fletching', 'fishing',
'firemaking', 'crafting', 'smithing', 'mining', 'herblore', 'agility',
'thieving', 'slayer', 'farming', 'runecrafting', 'hunter', 'construction'
];
var skills = {
'osrs': BASE_SKILLS,
'rs3': BASE_SKILLS.concat('summoning', 'dungeoneering', 'divination')
};
var urls = {
'osrs': 'http://services.runescape.com/m=hiscore_oldschool/index_lite.ws?player=',
'rs3': 'http://hiscore.runescape.com/index_lite.ws?player='
};
Meteor.methods({
lookup: function(player, game) {
if (!urls.hasOwnProperty(game)) {
game = 'rs3';
}
var url = urls[game].concat(encodeURIComponent(player));
result = Meteor.http.get(url);
$ = cheerio.load(result.content);
body = $.html();
parsed = Meteor.call('parseStats', body, skills[game]);
return parsed;
},
parseStats: function(raw, skillsList) {
var stats = raw.split('\n').slice(0, skillsList.length);
var statsObj = { };
stats.forEach(function(stat, index) {
var chunk = stat.split(',');
statsObj[skillsList[index]] = {
rank: +chunk[0],
level: +chunk[1],
xp: +chunk[2]
};
});
return statsObj;
}
});
In my client code, I'm testing lookup method manually by providing player name inside function as an argument:
Meteor.call('lookup', 'zezima', 'rs3', function(error, result) {
if (error) {
console.error(error);
}
console.log(result);
Session.set("data", result);
});
Template.rawdata.helpers({
getData: function() {
return Session.get("data");
}
});
Result in console:
{
agility: {
level: 99,
rank: 174,
xp: 100234567
},
attack: {
level: 99,
rank: 601,
xp: 127370193
},
construction: {
level: 99,
rank: 119,
xp: 141170001
},
and so on...
}
Obviously, when I call getData
inside my template in html and render it, it shows: [object Object]
. So I want to somehow iterate through objects and insert them into table, that will look like this one:
<table id="rs-hiscores">
<thead>
<tr>
<th>Skill name</th>
<th>Rank</th>
<th>Level</th>
<th>Xp</th>
</tr>
</thead>
<tbody id="rs-hiscore-data">
<tr>
<td>Agility</td>
<td>99</td>
<td>174</td>
<td>109317063</td>
</tr>
<tr>
<td>Attack</td>
<td>99</td>
<td>601</td>
<td>127370193</td>
</tr>
<tr>
<td>Construction</td>
<td>99</td>
<td>119</td>
<td>141170001</td>
</tr>
...and so on ...
</tbody>
</table>
How can I do that? And also - whould it be possible to sort results in the same order as skills are inside BASE_SKILLS
? Thank for help in advance.
Upvotes: 0
Views: 634
Reputation: 749
Okay so you're going to need the data in a decent array, in the order of BASE_SKILLS
, using Underscore to map the skills from your data to a new array, your getData
helper should look like this:
var data = Session.get('data');
var array = _.map( BASE_SKILLS, function(skillName){
var skill = data[skillName]
return {
name: skillName,
rank: skill.rank,
level: skill.level,
xp: skill.xp
};
});
return array;
This makes a neat array that looks like this:
[
{
name: "overall",
rank: 99,
level: 174,
xp: 109317063
},
{
name: "attack",
rank: 23,
level: 201,
xp: 256311563
},
...etc
]
Then you'll need to get those values into the html in the way you want.
<table id="rs-hiscores">
<thead>
<tr>
<th>Skill name</th>
<th>Rank</th>
<th>Level</th>
<th>Xp</th>
</tr>
</thead>
<tbody id="rs-hiscore-data">
{{#each getData}}
<tr>
<td>{{name}}</td>
<td>{{rank}}</td>
<td>{{level}}</td>
<td>{{xp}}</td>
</tr>
{{/each}}
</tbody>
</table>
You will have the lowercase keys in your table though, overall
instead of "Overall" but to get nice names you can just make a dictionary helper function that swaps the one for the other like so: {{getNiceName name}}
.
Upvotes: 1