Step 5: Use the Models
Tags: javascript, mongodb, express, beginners
Published: 2020-09-21 22:34:59

**Step 5: Use the models to create (or then update or delete) the documents (or records) you want to store in the database**

So far, we have completed four steps to be prepared and get ready to take this step.

We've designed two models for our app, **Post** and **User**. We've made sure the database was successfully connected. We've written **UserSchema** and **PostSchema** and explicitly defined which properties should be unique, have default values, or are required and which should not. Finally, we've used `mongoose.model()` to make models of these schemas.

Now, we have **User** and **Post** models at our disposal, and we are ready to create our first user. But first, let us make a few configurations to our app and create two forms for creating users and posts. 

```javascript
// app.js

const path = require('path');
// set path to the views folder
app.set('views', __dirname + '/views')

// set path to the public folder
app.use(express.static(path.join(__dirname, 'public')));
// allows to parse the submitted data with the request in req.body
app.use(express.urlencoded({extended: true}))
```
Create *public* and *views* folders at the root of your project, and inside the *views* folder add an *index.html* file.

 ```html
<!-- views/index.html -->
<!DOCTYPE html>
<html lang="en">
    <head>
    </head>
    <body>
        <div class="wrapper">
            <!-- 1 -->
            <!-- Create a form for creating users -->
            <!-- on submit it goes to /api/users/create/ -->
            <form action="/api/users/create/" method="POST">
                <h2>Create a New User</h2>
                <label for="username">Username</label>
                <input id="username" type="text" name="username" placeholder="Name"/>
                <label for="email">Email</label>
                <input id="email" type="text" name="email" placeholder="Email"/>
                <button type="submit">Create</button>
            </form>
            
            <!-- 2 -->
            <!-- Create a form for creating posts-->
            <!-- on submit it goes to /api/posts/create/ -->
            <form action="/api/posts/create/" method="POST">
                <h2>Create new posts</h2>
                <label for="title">Title</label>
                <input id="title" type="text" name="title" placeholder="Title (optinal)"/>
                <label for="content">Content</label>
                 <textarea id="content" type="text" col="25" rows="5"
                          name="content" placeholder="Content here" required>
                </textarea>
                <button type="submit">Create</button>
            </form>
        </div>
    </body>
</html>
```
We have two forms now:
1- A form for creating new users. When we submit it, it goes with the data it holds to the *"/api/users/create/"* route.
2- A form for creating new posts. When we submit it, it goes with the data it holds to the *"/api/posts/create/"* route.

Next, we need to add those routes to our app.

```javascript
// app.js
app.post("/api/users/create/",  /*pass for now*/);
app.post("/api/posts/create/",  /*pass for now*/);
``` 
Now, `app` knows about those two routes, but it doesn't know yet what functions to call when the forms we defined earlier send their data to those routes. These functions are called controllers.

**Let's define our controllers**

Creat a controllers folder at the root of your project and add *userControllers.js* and *postControllers.js* files to it.

```javascript
// contollers/userControllers.js
// get User model from ../models/User.js
const User = require('../models/User');

// our controller for creating new users
// or the function that gets called when the form 
// for creating new users is submitted
exports.createUser = (req, res)=>{
   // pass for now
}
```

```javascript
// contollers/postControllers.js

// get Post model from ../models/Post.js
const Post = require('../models/Post');

// our controller for creating new posts
// or the function that gets called when the form 
// for creating new posts is submitted
exports.createPost = (req, res)=>{
     // pass for now
}
```
Now, let's get back to `app.js` and specify the controllers for the routes we defined.

```javascript
// app.js

// the root route will show our two forms in /views/index.js/
app.get('/', (req, res)=>{
    res.sendFile(__dirname + '/views/index.html');
});

// we need userControllers to access createUser()
const userControllers = require('./controllers/userControllers');

// we need postControllers to access createPost()
const postControllers = require('./controllers/postControllers');

// add a new route to call createUser() 
app.post("/api/users/create/", userControllers.createUser);
// add a new route to call createPost() 
app.post("/api/posts/create/", postControllers.createPost);
```

So far, we:
1- Created two forms for creating users and posts in `views/index.html`, with actions that go to two different routes.
2- Added those routes to our app.
3- Defined the functions/controllers that get called when the forms are submitted and passed them to the `app.post` methods.

If you aren't already, run `nodemon app` and go to [http://localhost:3000/](http://localhost:3000/), you should see two simple forms.  

**Creating New Users** 
Lets' get to the fun part now and start interacting with the database and create new users.

```javascript
//models/User.js
// the schema we defined in a previous step
const UserSchema = new Schema({
    // if username is not provided "Anonymous" will get saved 
   // to the database instead
    username: {
         type: String, 
         default:"Anonymous",
        },
    // email has to be unqiue and always present when creating new users   
    email: {
        type: String,
        required: true,
        unique: true
    }
});
```

```javascript
// contollers/userControllers.js

// get User model from ../models/User.js
const User = require('../models/User');

exports.createUser = (req, res)=>{
   // 1
   const {username, email} = req.body;
   // 2
     // when the username is provided create a userObj with 
    // username and email properties
   // else create a userObj with just the email
     const userObj = username? { username: username, email: email}
                             : { email: email }
     // pass userObj to User
     const newUser = new User(userObj);
  // 3
  newUser.save()
         .then(user=>{
            res.json({msg:"newUser saved successfully", user:user})
         })
         .catch(err=>{
            console.log(err)
            res.json({msg:"Error has occured"})
         })
}
``` 
From *UseSchema* above, we know we only have two properties for creating new users: *username* and *email*.

And in the `creatuser()` controller:
First, we get the *username* and *email* properties from `req.body`.

```javascript
const {username, email} = req.body;
```
We know that they are named *username* and *email* because these are the names we gave to our form inputs.

```html
...
<input id="username" type="text" name="username" placeholder="Name"/>
                <label for="email">Email</label>
                <input id="email" type="text" name="email" placeholder="Email"/>
...

```
Second, we use **User** to create a newUser instance of **User** with the data we submitted with the form. That data could be *username* and *email* or only *email* 

```javascript
 const userObj = username? { username: username, email: email}
                         : { email: email }
     // pass the userObj to User
     const newUser = new User(userObj);
```

And finally, we try to save the newUser instance to the database.

```javascript
 newUser.save()
         .then(user=>{
            res.json({msg:"newUser saved successfully", user:user})
         })
         .catch(err=>{
            console.log(err)
          res.json({msg:"Error has occured"})
         });
```
Two things could happen when we use `newUser.save()` here:
Either `newUser` gets saved successfully, and we receive an object with `msg:"newUser saved successfully"` and a user object.
Or 
Some error occurs, and we receive an object with `msg:"Error has occurred"`

Let's now use the create users form and create a user with *firstUser* for the username and *firstuser@gmail.com* for the email, and anonymous user by providing the email only.

Now, you should be having two users in your *users* collection in the database.

![two users in the database](https://i.ibb.co/4YZrmvz/twousersadded.jpg)

Now, Let's write some posts. 

**Refrences**
[freeCodeCamp](https://www.freecodecamp.org/learn/apis-and-microservices/mongodb-and-mongoose/)
[the mongoosejs docs](https://mongoosejs.com/docs/guide.html).
[MDN](https://developer.mozilla.org/en-US/docs/Learn/Server-side/Express_Nodejs/mongoose)
[code.tutsplus](https://code.tutsplus.com/articles/an-introduction-to-mongoose-for-mongodb-and-nodejs--cms-29527#:~:text=These%20documents%20are%20saved%20inside,via%20the%20Model's%20schema%20definition.)