The goal of this final Mongo experience is to learn about the Simple Schema and Collection2 packages, the standard approach to enforcing consistency in documents created for Mongo collections in Meteor.
This is not a practice WOD because I could not find any Readings to introduce this material. So, please watch me do it first before trying it yourself:
For this experience, we will build upon the code we used in the last experience.
Create a branch of your meteor-mongo-practice repo called “simple-schema”.
Publish this branch (i.e. push it to GitHub).
Run meteor reset
and meteor run
to start up a fresh instance of the system.
Retrieve http://localhost:3000 in your browser to see a client instance of your meteor app.
Update the PeopleInitialization.js file to look like this:
import { people } from '../both/PeopleCollection.js';
if (people.find().count() === 0) {
people.insert({ first: 'Philip', last: 'Johnson', age: 60, city: 'Kailua' });
people.insert({ first: "Joanne", last: "Amberg", age: 58, city: "Kailua" });
people.insert({ first: "Jenna", last: "Corin", age: 31, city: "Boulder Creek" });
people.insert({ first: "Katie", last: "Kai", age: 25, city: "Palo Alto" });
people.insert({ first: "Doris", last: "Johnson", age: 93, city: "Naples" });
}
people.insert({ animal: "Dog", name: "Koa", city: "Pearl City" });
Once the system restarts, verify that Koa was successfully added to the People collection.
What this illustrates is that by default, Mongo places no constraints on the documents that can be inserted into a collection. This is almost never what we want!
The standard way to enforce a structure on the documents in a Mongo collection using Meteor is through a package called “Simple Schema” (the npm package is called simpl-schema, I guess because the correctly spelled package name was already taken).
To make sure we don’t inadvertantly add dogs to our People collection, we will add two packages to our Meteor app: SimpleSchema and Collection2. Simple Schema provides a way to specify constraints on the structure of Mongo documents, and Collection2 provides a way to attach a Simple Schema to a Meteor collection such that violating these constraints when inserting or updating documents will trigger an error.
To install both of these packages, follow the Collection2 installation instructions.
Replace the contents of the PeopleCollection.js file with this:
import { Mongo } from 'meteor/mongo';
import SimpleSchema from 'simpl-schema';
const peopleSchema = new SimpleSchema(
{
first: String,
last: String,
age: SimpleSchema.Integer,
city: String
}
);
export const people = new Mongo.Collection('People');
people.attachSchema(peopleSchema);
The first two lines import the Mongo and SimpleSchema classes so we can refer to them in our code.
Next, we define a variable called peopleSchema, which is bound to an instance of a SimpleSchema. SimpleSchema takes an object as its argument which defines key-value pairs to specify constraints on a Mongo document. In this case, we are specifying that a document must have exactly four fields: first, last, age, and city. Three of those fields must be Strings and one must be an Integer.
The second to last line defines the People collection.
The last line attaches the peopleSchema to the People collection. (The “attachSchema” method is provided by the Collection2 package.) This last line means that any document added to the People collection must satisfy those constraints. If they don’t, then an error will be thrown.
Now let’s check to see if the app runs correctly.
First, comment out the line that adds Koa the Dog to the People collection.
Then, invoke meteor reset
and meteor run
to restart your app with a fresh database.
You should see no errors in the console or in your client browser.
Now, uncomment the line that adds Koa the Dog, and save the file. When Meteor restarts, you should see the following error in both the console and your browser:
Error: First is required
at getErrorObject (packages/aldeed:collection2-core/collection2.js:453:15)
at [object Object].doValidate (packages/aldeed:collection2-core/collection2.js:435:13)
at [object Object].Mongo.Collection.(anonymous function) [as insert] (packages/aldeed:collection2-core/collection2.js:187:25)
at meteorInstall.server.PeopleInitialization.js (server/PeopleInitialization.js:10:8)
at fileEvaluate (packages/modules-runtime.js:333:9)
at require (packages/modules-runtime.js:228:16)
at /Users/philipjohnson/github/philipmjohnson/meteor-mongo-practice/app/.meteor/local/build/programs/server/app/app.js:116:1
at /Users/philipjohnson/github/philipmjohnson/meteor-mongo-practice/app/.meteor/local/build/programs/server/boot.js:338:34
at Array.forEach (native)
at Function._.each._.forEach (/Users/philipjohnson/.meteor/packages/meteor-tool/.1.5.2.xbr9sy++os.osx.x86_64+web.browser+web.cordova/mt-os.osx.x86_64/dev_bundle/server-lib/node_modules/underscore/underscore.js:79:11)
The error was thrown as soon as SimpleSchema discovered a discrepancy between the schema (which requires that there be a field called “first”) and the document (which doesn’t have a “first” field).
Also, it’s vital to note that this stack trace identifies the exact line of code where the error occurred (Line 10 of PeopleInitialization.js). So, it’s easy to see that the problem is with the attempt to insert Koa the Dog into the People collection.
If you again comment out the line (or delete it), then Meteor will restart and everything will return to normal. (You will have to refresh the page in your browser).
When you have finished this exercise, commit your code to GitHub. This is the way we can check that you carried out the instructions in this assignment. It also provides sample code for you to look at in future to remind yourself of how Simple Schema works with Meteor and Mongo.
If you’ve followed along, you should now have a basic idea of how to use Simple Schema. In brief:
You must install both the Simple Schema and Collection2 packages.
Define a schema for your collections. In this case, our schema was super simple. Read the documentation to learn about all of the possible approaches to constraints.
Attach the schema to your collection. Then, whenever you do an insert or update, Meteor will throw an error if the document is not structured correctly.
If you want to check to see if a document is valid before doing the insert, you can use the validate()
method. See the documentation for more details.
By the time and date indicated on the Schedule page, submit this assignment via Laulima. To submit, please provide the URL to your GitHub repository.
This is not a practice WOD, so you do not have to time yourself.