Share
Explore

Express with MONGO DB ROUTES lab workbook

Fun Fact: is created by . He coined the term .
More background on Mongo and Mongoose:
Watch this Explainer Video for an Overview of this Workbook:
Lab Workbook Part 1: JavaScript MONGOOSE API Code to create a Bookstore Database in Altas DB.
Lab Workbook Part 2: Front end CRUD operations on our MONGOOSE Database with Express.js.
Complete Node.js Application.
Review : mongoose express nodemon
nodemon index.js

Recalling our work in class on creating the MVC MONGO database and front ending the database with an Express.js server and html page:
Let’s make a 3 tier application to model the business domain of a bookstore:
megaphone

Part 1: Make a Node.js project with code using MONGOOSE API to create a MONGO database to make a book store with collections for books, customers, and customerorders.

Make 5 book records, 5 customer records, and 3 order records relating 3 customer to the purchase of 2 books each.


info

To create a comprehensive Node.js full stack web application with Mongoose and MongoDB, we must structure the content effectively by considering the following components:

Create a directory and in your VSC project, remember npm -init to create the package.json
Setting up the Project: Remember to import all the packages you are using.
Creating Database Schema: Create the schemas for the collections: books, customers, and customer orders. Include schema design considerations and how they relate to real-world entities.
Seeding Data: Insert mock data into the MongoDB database. Could use MONGODB Compass or write a mongoose script. This involves creating seed files and using Mongoose models to seed the database with 5 book records, 5 customer records, and 3 order records that relate 3 customers to the purchase of 2 books each.
CRUD Queries and Operations: In this section, demonstrate how to perform CRUD operations using Mongoose, such as querying books, adding new customers, and creating customer orders. This should cover basic find, create, update, and delete operations.
Error Handling and Best Practices: Discuss best practices for error handling, data validation, and ensuring data integrity within the database. Provide examples of error handling in Mongoose and Node.js.
Documentation: Emphasize the importance of documenting code and provide guidance on writing clear, concise, and meaningful comments within the codebase.
End-to-End Project Example: Demonstrate the simple web application that interacts with the MongoDB database using Node.js and Mongoose.

megaphone

Workflow to set up the Node.js project with Mongoose and create the database schemas:

Step 1: Create a project directory and initialize the Node.js project

Open the terminal and create a new directory for your project:
mkdir nodejs-bookstore cd nodejs-bookstore
Then, initialize the project using npm to generate the package.json file:
npm init
Follow the prompts to fill in the details or use the default values to create package.json.

Step 2: Setting up the Project:

Install required npm packages
You'll need to install the necessary npm packages for the project.
Run the following commands to install Mongoose and any other required packages:
npm install mongoose express mongo nodemon
Ensure mongoose and express are listed as dependencies in your package.json after installation.

Step 3: Creating Database Schema : done in file models.js

...

Option 2: Enable ES6 Modules in Node.js

If you prefer to use ES6 modules, you can configure your Node.js environment to support them:
Set "type": "module" in package.json:
Add "type": "module" to your package.json. This tells Node.js to treat JavaScript files as ES6 modules.
Your package.json should look something like this:
{ "name": "your-app", "version": "1.0.0", "type": "module", // ... other fields }
Use .mjs Extension:
Alternatively, you can use the .mjs extension for your JavaScript files if you prefer not to change the package.json settings. Simply rename your models.js to models.mjs.
After making these changes, you should be able to use the ES6 import/export syntax without encountering the error.

Note on Node.js Version

Node.js has been gradually adding support for ES6 modules, and it's fully available in recent versions. Ensure you are using a Node.js version that supports ES6 modules (Node.js version 13.2.0 or later). You are currently using Node.js v20.9.0, which supports ES6 modules, so you should be good to go once you apply one of the above options.
...



***** Create a new file called models.js, for defining the Mongoose schemas.
////////////////
The models.js file is a vital part of a typical Node.js application that uses Mongoose for database interaction.
In a real-world scenario, the models.js file would be created in a separate "models" or "db" directory within the project's directory structure. This file contains the Mongoose schema definitions for the various data entities utilized in the application, such as books, users, etc.
Here's an example of how the models.js file might be structured:
// models.js

import mongoose from 'mongoose';

const bookSchema = new mongoose.Schema({
title: String,
author: String,
genre: String,
// Other book properties...
});

const userSchema = new mongoose.Schema({
username: String,
email: String,
// Other user properties...
});

// Book and user are MODELS
// model is a in program memory data representation of an entity in the business domain that you are writing the software application to automate.

const Book = mongoose.model('Book', bookSchema);
const User = mongoose.model('User', userSchema);

export { Book, User };
In this example, models.js contains the schema definitions for the Book and User models.
These schemas define the structure of the data entities, including their properties and types.
Once created, this models.js file can be imported and utilized in other parts of the application, such as in the server-side code, to interact with the MongoDB database using Mongoose.
///////////////
In the context of Mongoose and MongoDB:
bookSchema:
bookSchema is a Mongoose schema that defines the structure of documents within the 'books' collection in MongoDB. It specifies the expected fields and their data types for each book document. In the provided example, bookSchema includes fields for the title, author, genre, and potentially other properties relating to a book entity.
userSchema:
Similarly, userSchema is a Mongoose schema that outlines the blueprint for documents within the 'users' collection in MongoDB. It defines the expected fields and their data types for each user document. In the example given, userSchema includes fields for the username, email, and possibly other properties relevant to a user entity.
Book and User:
Book and User are Mongoose models that are created using the mongoose.model method. These models are used to interact with the MongoDB collections ('books' and 'users', respectively) that adhere to the defined schemas (bookSchema and userSchema).

By creating models from these schemas, Mongoose provides an interface for conducting operations such as creating, reading, updating, and deleting (CRUD) documents in the respective collections.
bookSchema and userSchema serve as blueprints that define the expected structure and data types for documents in the 'books' and 'users' collections.

Book and User are Mongoose models that provide a way to interact with these collections, leveraging the defined schemas for streamlined and consistent data management.
The models.js file commonly defines Mongoose schemas and creates corresponding Mongoose models.

Here's a more detailed breakdown:
Schema are structures.
Models are data entities which realize those structures.
Models.js setups the schema and creates the Models.
Models are the in-memory OBJECTS we interact with in our mongoose code.
Defining Schemas: The Mongoose schemas, such as bookSchema and userSchema in the provided example, define the structure of the data entities within a MongoDB database. Schemas specify the properties, data types, validation rules, and other configuration for documents in a specific collection.
Creating Models: Mongoose models, such as Book and User, are created from the defined schemas using the mongoose.model method. These models are responsible for providing an interface for interacting with the MongoDB collections according to the defined schemas. They represent the business domain entities and handle operations like creating, reading, updating, and deleting documents in the database.
Therefore, the models.js file indeed plays a crucial role in defining the structure of the data domain, via schemas, and creating the corresponding models to handle data records within the business domain.
ECMAScript 6 Modules Import / Export
Loading…

In Node.js, module imports and exports are used to encapsulate code within separate files and enable the sharing of functionality between different parts of the application.
When a file (module) is imported, its contents become available for use in the importing file.
When a file (module) is exported, it makes certain components of the file available for use in other files.
In the context of the code we've discussed, I'll explain how module imports and exports can be performed with examples based on the existing code:

Exporting from models.js:

In models.js, the Mongoose models are typically exported to make them accessible to other parts of the application. Here's how it's done using module.exports:
javascript// models.js const mongoose = require('mongoose');
const bookSchema = new mongoose.Schema({ title: String, author: String, genre: String, // Other book properties... });
const Book = mongoose.model('Book', bookSchema);
module.exports = { Book };
In this example, the Book model is defined and then exported using module.exports as an object. This makes Book available for use in other files that import models.js.

Importing into seed.js:

To utilize the exported Book model in seed.js, it can be imported using require:
seed.js
// Using ES6 import syntax
import mongoose from 'mongoose';
import { Book } from './models.js'; // Make sure the path is correct

// ... rest of your code

// Importing the Book model
// Rest of the seeding logic using the Book model
Here, the Book model is imported from models.js using the require statement, allowing seed.js to access and use the Book model for seeding the database with sample book records.
By using the require function to import and module.exports to export, we can achieve modularization and code reuse in a Node.js application.
This allows for better organization, maintainability, and reusability of the application's codebase.
I anticipate this provides a clear understanding of module imports and exports in the context of the provided code. If you have further queries or need additional examples, feel free to ask!

In the provided starter code, replace the template information with real book titles and posit some names for customers:

Include 5 book records, 5 customer records, and 3 order records.
We'll also establish the relationships between customers and their orders, as well as the books included in each order.
First, let's create the seed data for the initial records.
Create a new file, for example seed.js, to populate the database with records:

Following the methods we used in class: REPLACE THE REFERENCES TO LOCAL MONGO DB SERVER WITH THE MONGO DB REALM CREDENTIALS YOU CREATED IN CLASS ON THURSDAY.

javascript:
// seed.js// Using ES6 import syntax
import mongoose from 'mongoose';
import { Book, Customer, Order } from './models.js'; // Importing all required models
// Function to seed initial data
async function seedData() {
try {
// Create 5 book records
const books = await Book.create([
{ title: 'Book 1', author: 'Author 1' },
{ title: 'Book 2', author: 'Author 2' },
{ title: 'Book 3', author: 'Author 3' },
{ title: 'Book 4', author: 'Author 4' },
{ title: 'Book 5', author: 'Author 5' }
]);

// Create 5 customer records
const customers = await Customer.create([
{ name: 'Customer 1', email: 'customer1@example.com' },
{ name: 'Customer 2', email: 'customer2@example.com' },
{ name: 'Customer 3', email: 'customer3@example.com' },
{ name: 'Customer 4', email: 'customer4@example.com' },
{ name: 'Customer 5', email: 'customer5@example.com' }
]);

// Create 3 order records
const orders = await Order.create([
{ customer: customers[0]._id, books: [books[0]._id, books[1]._id] },
{ customer: customers[1]._id, books: [books[2]._id, books[3]._id] },
{ customer: customers[2]._id, books: [books[4]._id, books[1]._id] }
]);

console.log('Seed data created successfully');
} catch (error) {
console.error('Error seeding data:', error);
} finally {
// Close the database connection
mongoose.connection.close();
}
}

// Call the seedData function
seedData();


In the provided program, the names of the schemas and their respective schema items are:
Schema Names:
Book
Customer
Order
Schema Items:
Book Schema:
title: String (required)
author: String (required)
Customer Schema:
name: String (required)
email: String (required)
Order Schema:
customer: ObjectId (references Customer collection, required)
books: Array of ObjectIds (references Book collection, required)

In the seedData function, these schema items are utilized to create initial records for the Book, Customer, and Order collections in the MongoDB database.
Each record is created using the respective schemas defined in the models.js file.
This establishes a clear understanding of the schema names and their respective items involved in creating and populating the database records in the provided program.

In this seed file, we use the create method provided by Mongoose to insert the initial data into the respective collections.

After adding the seed data, execute the seed.js file using Node.js to populate the database with the initial records.
By incorporating this expanded code, you can fulfill the requirement of creating 5 book records, 5 customer records, and 3 order records for the Node.js project with Mongoose and MongoDB.
megaphone

Now that you have gotten this far, let’s amp up our game to push the data in the database on MONGODB Atlas:

How to connect to a MongoDB database in MongoDB Atlas, create a database, and then seed initial data:
Create a Node.js program. Call it any name you like:
Remember to use your own connection credentials for MONGO DB Atlas that we setup on Thursday:

const mongoose = require('mongoose');
// remember your models.js file that you made a while ago? Now make it available to this
// program with require
const { Book, Customer, Order } = require('./models');
// MongoDB Atlas connection URI const MONGODB_URI = 'your-mongodb-atlas-connection-uri';
// Connect to MongoDB Atlas database and seed initial data async function seedData() { try { // Establish MongoDB Atlas database connection await mongoose.connect(MONGODB_URI, { useNewUrlParser: true, useUnifiedTopology: true });
// Create 5 book records const books = await Book.create([ { title: 'Book 1', author: 'Author 1' }, { title: 'Book 2', author: 'Author 2' }, { title: 'Book 3', author: 'Author 3' }, { title: 'Book 4', author: 'Author 4' }, { title: 'Book 5', author: 'Author 5' } ]);
// Create 5 customer records const customers = await Customer.create([ { name: 'Customer 1', email: 'customer1@example.com' }, { name: 'Customer 2', email: 'customer2@example.com' }, { name: 'Customer 3', email: 'customer3@example.com' }, { name: 'Customer 4', email: 'customer4@example.com' }, { name: 'Customer 5', email: 'customer5@example.com' } ]);
// Create 3 order records const orders = await Order.create([ { customer: customers[0]._id, books: [books[0]._id, books[1]._id] }, { customer: customers[1]._id, books: [books[2]._id, books[3]._id] }, { customer: customers[2]._id, books: [books[4]._id, books[1]._id] } ]);
console.log('Seed data created successfully'); } catch (error) { console.error('Error seeding data:', error); } finally { // Close the database connection mongoose.connection.close(); } }
// Call the seedData function to seed initial data seedData();
In this modified version, the MONGODB_URI variable holds the connection URI obtained from MongoDB Atlas. The mongoose.connect method is used to connect to the MongoDB Atlas database by passing the MONGODB_URI and database connection options.
This code demonstrates how to establish a connection to a MongoDB database hosted on MongoDB Atlas and then seed initial data into that database using Mongoose.
Remember to replace 'your-mongodb-atlas-connection-uri' with the actual connection URI provided by MongoDB Atlas.

Remember to keep track of the names of your database, schema, and data objects.

error

Below is a stand-alone Node.js program that uses Mongoose to display all the collections and their respective data records in the MongoDB database:

javascript
// displayCollectionsData.js const mongoose = require('mongoose'); const { Book, Customer, Order } = require('./models');
// Establish a connection to the MongoDB database
// replace this line with the connection credentials for mongo db Atlas:
mongoose.connect('mongodb://localhost:27017/bookstore', { useNewUrlParser: true, useUnifiedTopology: true });
// Function to display all collections and their records async function displayCollectionsData() { try { // Fetch all book records const books = await Book.find().exec(); console.log('Books collection:'); console.log(books);
// Fetch all customer records const customers = await Customer.find().exec(); console.log('Customers collection:'); console.log(customers);
// Fetch all order records const orders = await Order.find().populate('customer').populate('books').exec(); console.log('Orders collection:'); console.log(orders); } catch (error) { console.error('Error fetching data:', error); } finally { // Close the connection mongoose.connection.close(); } }
// Call displayCollectionsData function displayCollectionsData();
In this stand-alone Node.js program, we first establish a connection to the MongoDB database using mongoose.connect. We then define a function displayCollectionsData to fetch and log all the records from the books, customers, and orders collections.
We use Mongoose methods like find and populate to retrieve the records and their referenced data.
Want to print your doc?
This is not the way.
Try clicking the ⋯ next to your doc name or using a keyboard shortcut (
CtrlP
) instead.