Creating the todo model
Now, as we have already talked about, inside of MongoDB, your collections can store anything. I could have a collection with a document that has an age property, and that's it. I could have a different document in the same collection with a property name; that's it. These two documents are different, but they're both in the same collection. Mongoose likes to keep things a little more organized than that. What we're going to do is create a model for everything we want to store. In this example, we'll be creating a Todo model.
Now, a Todo is going to have certain attributes. It's going to have a text attribute, which we know is a string; it's going to have a completed attribute, which we know is a Boolean. These are things we can define. What we're going to do is create a Mongoose model so Mongoose knows how to store our data.
Right below the mongoose.connect statement, let's make a variable called Todo, and we're going to set that equal to mongoose.model. The model is the method we're going to use to create a new model. It takes two arguments. The first one is the string name. I'm going to match the variable name on the left, Todo, and the second argument is going to be an object.
mongoose.connect('mongodb://localhost:27017/TodoApp');
var Todo = mongoose.model('Todo', { });
This object is going to define the various properties for a model. For example, the Todo model is going to have a text property, so we can set that up. Then, we can set text equal to an object, and we can configure exactly what text is. We can do the same thing for completed. We're going to have a completed property, and we're going to want to specify certain things. Maybe it's required; maybe we have custom validators; maybe we want to set the type. We're also going to add one final one, completedApp, and this is going to let us know when a Todo was completed:
var Todo = mongoose.model('Todo', { text: { }, completed: { }, completedAt: { } });
A createdApp property might sound useful, but if you remember the MongoDB ObjectId, that already has the createdAt timestamp built in, so there's no reason to add a createdApp property here. completedAt, on the other hand, is going to add value. It lets you know exactly when you have completed a Todo.
From here, we can start specifying the details about each attribute, and there's a ton of different options available inside of the Mongoose documentation. For now though, we're going to keep things really simple by specifying the type for each, for example, text. We can set type equal to String. It's always going to be a string; it wouldn't make sense if it was a Boolean or a number.
var Todo = mongoose.model('Todo', { text: { type: String },
Next, we can set a type for completed. It needs to be a Boolean; there's no way around that. We're going to set type equal to Boolean.
completed: { type: Boolean },
The last one we have is completedAt. This is going to be a regular old Unix timestamp, which means it's just a number, so we can set the type for completedAt equal to Number:
completedAt: { type: Number } });
With this in place, we now have a working Mongoose model. It's a model of a Todo that has a few properties: text, completed, and completedAt.
Now in order to illustrate exactly how we create instances of this, we're going to go ahead and just add one Todo. We're not going to worry about fetching data, updating data, or deleting data, although that is stuff that Mongoose supports. We'll be worrying about that in the following sections, as we start building out the individual routes for our API. For now, we're going to go over just a very quick example of creating a brand-new Todo.