Games collection
A lot of these steps we have covered in part 1, so I won't go into too much explanation.
Firstly let's create the games collection:
both/collections/games.js
Games = new Mongo.Collection('games');
We'll also create a dummy game so we have something to play with:
server/seeds.js
Meteor.startup(function () {
if (Teams.find().count() === 0) {
// Create some teams
[
{name: "Barcelona"},
{name: "Real Madrid"},
{name: "Matt's team"}
].forEach(function(team){
Teams.insert(team);
});
// Create a game
var team1 = Teams.find().fetch()[0];
var team2 = Teams.find().fetch()[1];
var game = {
completed: false,
createdAt: new Date(),
teams: [
{name: team1.name, _id: team1._id, score: 0},
{name: team2.name, _id: team2._id, score: 0}
]
};
Games.insert(game);
}
});
Note that I use Teams.find().fetch(). This is because Teams.find() alone doesn't return an array, but rather an object called a 'cursor'. The Meteor docs describe it well:
"
findreturns a cursor. It does not immediately access the database or return documents. Cursors providefetchto return all matching documents,mapandforEachto iterate over all matching documents, andobserveandobserveChangesto register callbacks when the set of matching documents changes.""Cursors are a reactive data source. On the client, the first time you retrieve a cursor's documents with
fetch,map, orforEachinside a reactive computation (eg, a template or autorun), Meteor will register a dependency on the underlying data. Any change to the collection that changes the documents in a cursor will trigger a recomputation. To disable this behavior, pass{reactive: false}as an option tofind."
So a cursor is like an open door to a collection in the database. To retrieve the actual documents as JSON you'll need to walk through the door and collect it by calling fetch().
While the code looks correct it's actually missing one thing. Remember in our data design we decided to store an array of game ids on each team? Lets update our seeds to take this into account:
server/seeds.js
Meteor.startup(function () {
if (Teams.find().count() === 0) {
// Create some teams
[
{
name: "Barcelona",
gameIds: []
},
{
name: "Real Madrid",
gameIds: []
},
{
name: "Matt's team",
gameIds: []
}
].forEach(function(team){
Teams.insert(team);
});
// Create a game
var team1 = Teams.find().fetch()[0];
var team2 = Teams.find().fetch()[1];
var game = {
completed: false,
createdAt: new Date(),
teams: [
{name: team1.name, _id: team1._id, score: 0},
{name: team2.name, _id: team2._id, score: 0}
]
};
var gameId = Games.insert(game);
// Add this game to both teams gameIds
Teams.update({_id: team1._id}, {$addToSet: { gameIds: gameId}});
Teams.update({_id: team2._id}, {$addToSet: { gameIds: gameId}});
}
});
The only new concept here is the $addToSet operator. The Mongo docs sum it up best:
"The
$addToSetoperator adds a value to an array only if the value is not already in the array. If the value is in the array,$addToSetdoes not modify the array."
Basically whenever you want to do something more fancy than change a simple value like a String, I suggest googling it (eg "mongo add to array unique") before trying to wangle it into $set. Or you can peruse the possible options here. If I hadn't found $addToSet I would've had to write more code to make sure the array had unique values.
Remember to reset your data so the game gets inserted:
meteor reset
meteor