Skip to content

10.4 Big Feelings

New Material
Use Node.js and MongoDB Atlas to create the back end for the Big Feelings front end you created following the exercises in chapter 10. Then publish your full-stack application on Vercel.

Screenshot of the Big Feelings web page. The final version of the prompt for Chapter 10 can be found online https://big-feelings.vercel.app

Set up the full-stack version of Big Feelings.
  1. Using Codespaces (or VS Code if you are developing locally) open the big-feelings-starter project repository that you edited in Chapter 10.
  2. Like the Bad Password API (BPA), we modified the project structure to make it easier to publish the front-end version on Github Pages. Move index.html and the assets folder into the public folder. You’ll see the structure is similar to our Bad Password API, with a api/index.js and api/routes.js file.
  • package.json Meta information and project dependencies
  • Directoryapi Server files
    • Directorydata/ Testing data
    • Directorydatabase/ Scripts to help connect and use the database
      • mongodb.js The database script
    • index.js Run the server using routes.js
    • routes.js Contains the endpoints that return data
  • Directorypublic Static files go here
    • Directoryassets/
    • index.html Client side JS

This project has two parts. The back-end scripts inside api/ that run on the server and respond to requests for data from the front-end files index.html etc. in the browser.

  1. Open api/database/mongodb.js. The database code is organized in its own file to “separate the concerns” and organize scripts by their specific tasks. This file connects to the database to let us save and retrieve data. Also notice that the database functionality (e.g. to create and insert data in the table) is exported inside an object called db to make it simpler to run the database queries from api/routes.js.
  2. Open package.json and you’ll see (like BPA) that the dependencies include express, as well as new packages like mongodb. To install them run:
npm install
  1. Start the server with nodemon (see 9.3 Using Node.js). A message will appear in the terminal with the URL. Open this page in a browser to check that all is well.
Your app is listening at: http://localhost:3000
Create a MongoDB Atlas account and database.

Before you can use our database module you’ll need to create a database using Atlas, a professional web service that provides access to MongoDB databases. (see the latest guidance in their MongoDB Atlas Tutorial tutorial).

  1. Click “Get Started” on their landing page and create an Atlas account
  2. At the end of the sign-up process, you will be prompted to create an organization (to organize users) and a project (to organize clusters and databases). We created a project named criticalwebdesign.
  3. Login to the Dashboard https://cloud.mongodb.com/ and follow the steps in Deploy a Free Cluster to create a new free-tier cluster. We named our cluster big-feelings, left all the default options as they were, and clicked “Create Deployment.”
  1. Next you’ll be prompted to create a user to access databases in your cluster. We used the default user and password they generated. Save these somewhere safe! Note also your current IP address will be added to the list of allowed connections. This is a security feature that prevents someone at a different location from trying to guess your information.
  2. Now it’s time to choose a connection method. This is important because you’ll be connecting to the database from another machines and you need to give permission for Codespaces (and eventually, Vercel) to connect to Atlas. Click “Choose a connection method,” then select “Drivers” and choose Node.js. We’ve already added mongodb to the dependencies for this project, so you just need to copy the connection string that contains your username, password, and other details to a safe place and proceed to the next section. It will look something like the following:
mongodb+srv://USER:PASS@CLUSTER.[...].mongodb.net/?appName=CLUSTER
Best practices for sensitive information (e.g. connection strings) in full-stack projects.

The connection string you created in the previous step contains your database credentials. Obviously you don’t want someone with bad intentions to be able to access this. So, don’t save in your front-end code. You also don’t want to commit this data to your Git repository which may allow someone to see it on Github.

While your frontend code will connect to your API, the connection string will only be accessible on the backend server, which will keep it safe from prying eyes. There are many ways to do this, but we are using the common .envenvironment variables” file. You’ll save two versions of this file, one for testing on your own computer, and then another in Vercel when you publish your project.

  1. In your repo, rename the .env.example file in the root of your project to .env.
  1. Paste the following template code into the file:
MONGODB_URI="YOUR_CONNECTION_STRING"
NODE_ENV="test"
  1. Replace the text YOUR_CONNECTION_STRING with your own connection string.
  2. Open your .gitignore file and confirm that .env is among the list of files to be ignored by Git so you do not commit this file!
Test a MongoDB Atlas database connection.

With the connection string in place you can test your database connection using our test script.

  1. In Atlas, make sure your current IP address is allowed to connect.
    1. Go to https://cloud.mongodb.com/
    2. Click “Clusters” on the left
    3. Click “Database & Network Access” on the left
    4. Click “IP Access List” on the left
    5. Click the “Add IP Address” button
  1. Quit the server with Ctl+c
  2. Run our database test script using nodemon:
nodemon api/database/mongodb-test.js
  1. In the Terminal confirm you can see the results of the test script, including ping, stats, etc. Every time you run this script it will add a single entry with random data.

mongodb add IP address

  1. Verify that data was saved in your database by going to
    1. Go to https://cloud.mongodb.com/
    2. Click “Data Explorer” on the left
    3. Click “Connect” on your cluster in the list
    4. Expand your cluster and database and select the collection.

mongodb data explorer Data inside cwd-test-cluster (cluster) > bigFeelings (database) > feelings (collection)

Connect to and query the database using Node.js.

Now that you have confirmed you can connect from your IP address to your database, you can switch to using your own database with this project.

  1. Quit the database test script with Ctl+c and start the project with nodemon. Go to http://localhost:3000/ and you should see the map. Note it is still getting data from our finished API.

  2. In api/routes.js import our database module

// 👉 import database reference here (Chapter 10 wiki) ...
import db from "./database/mongodb.js";
// 👈
  1. Now you can add API endpoints that call the functions exported from our module. First, make sure the API is working. Test the root endpoint at http://localhost:3000/api and you should see the following:
{"message":"hello"}
  1. Add the below function to api/routes.js (look for our finger emojis!) to retrieve data for the map. This route will use the db.getAll() function to query the database for all records. It uses await to make sure and wait for the query to finish so that it has results before sending a response. Test this route now in a new browser window by going to http://localhost:3000/api/feelings. You should see an empty array only because there is no data in the database, yet…
// 👉 add endpoint to get all the rows in the database (Chapter 10 wiki) ...
router.get("/api/feelings", async function (req, res) {
let result = await db.getAll();
res.json(result);
});
// 👈
  1. Add this endpoint below the code you added above to api/routes.js to add test data to the database. This route is not meant to be public, we are enabling it temporarily to add testing data only. Each time you load this page http://localhost:3000/api/addOneTest you will insert a new entry with random information. You can use the Atlas Data Explorer or the feelings endpoint to test it http://localhost:3000/api/feelings
// 👉 add endpoint to insert test data (Chapter 10 wiki) ...
router.get("/api/addOneTest", async function (req, res) {
let result = await db.addOneTest();
res.send({ message: result });
});
// 👈

JSON Data from mongodb at the feelings endpoint

  1. Now that you have feelings in the database you can change your frontend to point to your own backend API. Add this line to change the URL under the original baseurl declaration in public/assets/js/main.js and visit your site to see your data on the map http://localhost:3000
// 👉 add new base url to pull from your own database (Chapter 10 wiki) ...
baseurl = "";
// 👈

Markers Markers appear on the map for each feeling. Always keep your console open in case you have errors!

Enable form submissions on the map.

You may notice the Leaflet popup that appears if you click on the map, though nothing happens in your project if you click submit. With the form wired up, we can now connect the web form to let users submit new data.

  1. In public/assets/js/main.js find the submitForm() function. This is called when a user clicks submit. Add the following code to store the form data into a variable called data and log it. If you reload your page and test your form you will see a JS object of form inputs in the console.
function submitForm(e) {
// 👉 add code inside this function (Chapter 10 wiki) ...
e.preventDefault();
let data = getFormData();
console.log(data);
// 👈
}
  1. We’ve already added a /api/feeling POST endpoint that receives the request from the form and updates the database. Look inside api/routes.js and you will notice it uses router.post() instead of router.get().
  2. This means your fetch() function on the front end needs to send this data using a POST request. Add the following to the bottom of submitForm() to create a new options object you can use with fetch() that sets the method to POST, adds a special header to inform the server it is sending JSON data, and stores the data from the form in body of the request. The JSON.stringify() function converts a data object to the text equivalent (a.k.a. “serialization”) so it can be sent over the internet.
function submitForm(e) {
// step 1 - get form data
e.preventDefault();
let data = getFormData();
console.log(data);
// step 2 - create options object to send data
let options = {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(data),
};
}
  1. Now add the fetch() code below to send the data to the server. The route will return an updated JSON object, which you can use to call updateMap(json) and thencall showSuccessMsg() to let the user know everything worked. You can test your project now, watching the console and make sure everything works.
function submitForm(e) {
// step 1 - get form data
e.preventDefault();
let data = getFormData();
console.log(data);
// step 2 - create options object to send data
let options = {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(data),
};
// step 3 - use fetch to send data
fetch(baseurl + "/api/feeling", options)
.then((response) => response.json())
.then(async (json) => {
await updateMap(json);
showSuccessMsg("Your feeling was added");
});
}
Publish your project on Vercel for the world to see.

Follow the process we described in Module 9.4 Publish a Website with Vercel to publish your website on Vercel.

Add the MONGODB_URI environment variable in your Vercel account.

  1. Log in to your Vercel dashboard and select your project.
  2. Click on the Settings tab and select Environment Variables.
  3. Add the variable:
    1. Environments: Choose “All Environments”
    2. Name: Enter the key MONGODB_URI.
    3. Value: Paste your MongoDB connection string from MongoDB Atlas.
  4. Click the Save button.
  5. To ensure the new variable is applied, you must redeploy your project.

This step is required to allow your API on Vercel to connect to your Atlast cluster.

  1. In Atlas go to the Database & Network Access page for your project.
  2. Navigate to the IP Access List tab.
  3. Click Add IP Address.
  4. Select Allow Access from Anywhere or manually enter 0.0.0.0/0.
  5. Republish your project!

Make it live using

vercel --prod