DEV Community

Cover image for Let’s build and deploy a Full Stack Next.js App: Part 2
Winner Musole Masu
Winner Musole Masu

Posted on • Updated on

Let’s build and deploy a Full Stack Next.js App: Part 2

In this part, we are going to connect our Next.js app to a remote MongoDB database.

In case you missed part 1 of this tutorial series, click HERE to catch up.

As called in the title, we are going to add more features to the food Next.js App, to make it FullStack; it will be blending client-side and server-side. This one app will store and fetch data straight to and from the server and render finished pages.

1. Let’s connect to Mongo

First, run $ npm run dev in the terminal on the project directory. Have a look at the Home page on http://localhost:3000;
next js home page

It displays a card of a meal item that contains the image of a delicious meal, the name of the meal, the number of cooked dishes and the name of the chef. At the moment, the information inside the meal item is hard coded and static. Let’s go ahead and store it in a real database.

The project directory should look like the directory below:
Project dir

1.1 Build the back-end Api:

Here, we are going to build a back-end API together with the react front-end in this same project. For this, we will use special pages called “API Routes”.

Go ahead, in the “/pages” directory, create a directory named “/api”, in “/api” add a new file called “new-meal.js”.

Note: “any file added in “/pages/api” directory will be treated as an API endpoint and will be mapped as “/api/the_name_of_the_file.js”

For this project case, the API endpoint is => “/api/new-meal”.

1.2 Before adding any code in the "new-meal.js" file, the API endpoint; if you don’t have a MongoDB account, create one HERE.

1.3 After a successful login/sign up, you will be redirected here:

Create an organization
You are asked to create a new organization, so click on the green button “Create an Organization” and follow these steps:

  1. Click on "Create an Organization",
  2. Next, Name your organization,
  3. Click on the "Next" button at the bottom,
  4. And Click on "Create Organization" to give yourself access permissions. CREATE ORG GIF

Great, now that you created an organization, go ahead, create a new project;
create new project

1.4 Click on the green button “New Project” at the top-right, as shown in the page above:

Then follow these steps:

  1. Click on "New Project",
  2. Next, Name your project,
  3. Click on the "Next" button,
  4. Final, click on "Create Project" to give yourself access permissions as a Project Member. create project gif

1.5 Good job, now let’s build this project database:

Click on the green button “Build a Database” below:
build database

Follow these steps to build the database:

  1. After the click on "Buid a Database", choose the Free and Hobby deployment option,
  2. Click on "Create",
  3. On the next page, scroll-down, give a name to your Cluster and click on "Create Cluster",
  4. Wait about 3 minutes for the deployment. build a database

This is what waiting for 3 minutes deployment looks like:
wait for deployment
So be patient ...

Hope that this process was not long. Now, let’s connect the application to the newly created Database. You will need to add a database user and add your computer IP address, to let it have access to your cluster.

1.6 Add a Database User:

Cluster page
In the SECURITY section, click on "Database Access" and follow the steps below:

  1. Click on "Add New Database User",
  2. Insert the database username and the password, better write it down somewhere,
  3. And at the bottom,click on "Add User".

add database user

1.7 Add your computer IP address:

Still in the SECURITY section, click on "Network Access" and follow the steps:

  1. Click on "Add IP Address",
  2. Add your IP address by clicking on "ADD CURRENT IP ADDRESS" button in modal box,
  3. And click on "Confirm".

Add ip address

Super guys, now let's go back to the API endpoint, to connect the App to mongo.

1.8 Install mongodb in the project:

Open the terminal, on the project directory put this:

$ npm install  mongodb
Enter fullscreen mode Exit fullscreen mode

1.9 Import mongodb in the API endpoint js file and connect to mongo:

But before that, let's go to grab the Application Connection String that will connect the app to the cluster created earlier.
Go back to MongoDB, in DEPLOYMENT section:

  1. Click on "databases",
  2. Then click on "Connect",
  3. Choose the second connection method labelled "Connect your application",
  4. Copy the application connection string, that will be pasted into the project code.

Grab Mongo Uri

Back to the project, open "new-meal.js" in "/pages/api/" directory and put the code below it, but replace the value of const DATABASE_PASSWORD by the password you put while adding the database user in sub-point 1.6:

import { MongoClient } from "mongodb";

const handler = async (req, res) => {
  const DATABASE_NAME = "FoodApp";
  const DATABASE_PASSWORD = "1234567H";

  if (req.method === "POST") {
    const client = await MongoClient.connect(
      `mongodb+srv://masu:${DATABASE_PASSWORD}@foodapp.0tpop.mongodb.net/${DATABASE_NAME}?retryWrites=true&w=majority`
    );
    const db = client.db();
    const mealsCollection = db.collection("meals");
    await mealsCollection.insertOne(req.body);

    client.close();

    res.status(201).send({ Message: "Meal inserted" });
  }
};

export default handler;
Enter fullscreen mode Exit fullscreen mode

In code above, There is some modification with the application connection string that you copied early. So just paste and modify it as it's done in the GIF image below:
mongo uri altered

Basically, the application connection string is pasted in the file where, const DATABASE_NAME replaced "myFirstDatabase" and const DATABASE_PASSWORD replaced "<password>" in the string connection.

Again Good job, now the API endpoint is ready to be used.

1.10 Add a component page named “new-meal.js” in the “/pages” directory:

This is the form that we will use to add new meal. Put the code below in the page :

import { useRef } from "react";
import { useRouter } from "next/router";
const NewMealForm = () => {
  // use of useRef to capture input value
  const mealNameInputRef = useRef();
  const mealImagePathInputRef = useRef();
  const mealNumberOfDishInputRef = useRef();
  const chefInputRef = useRef();

  // use of useRouter from next/router to redirect this page to the Homepage
  const router = useRouter();

  // implementation of newMealHandler function
  const newMealHandler = async (event) => {
    event.preventDefault();

    // store meal data in an object
    const mealData = {
      name: mealNameInputRef.current.value,
      image_path: mealImagePathInputRef.current.value,
      dishes: mealNumberOfDishInputRef.current.value,
      chef: chefInputRef.current.value,
    };

    // use of Fetch API to make a request to the new-meal api and get back a response
    const response = await fetch("/api/new-meal", {
      method: "POST",
      body: JSON.stringify(mealData),
      headers: {
        "content-Type": "application/json",
      },
    });

    // parses JSON response into native JavaScript objects
    const data = await response.json();

    console.log(data);

    // redirects this page to the Homepage
    router.replace("/");
  };

  const INPUT_STYLE =
    "my-2 p-2 border border-gray-300 focus:ring-2 focus:ring-indigo-300 focus:ring-opacity-50 focus:outline-none w-full h-10 rounded-md";

  return (
    <div className="flex-col px-12 py-12 max-w-3xl mx-auto shadow-xl rounded-2xl">
      <h1 className="font-light text-4xl">Add a new Meal </h1>
      <form onSubmit={newMealHandler}>
        <input
          type="text"
          placeholder="Meal Name"
          required
          ref={mealNameInputRef}
          className={INPUT_STYLE}
        />
        <input
          type="text"
          placeholder="Image Path"
          required
          ref={mealImagePathInputRef}
          className={INPUT_STYLE}
        />
        <input
          type="number"
          max="5"
          min="1"
          placeholder="Number of Dishes"
          required
          ref={mealNumberOfDishInputRef}
          className={INPUT_STYLE}
        />
        <input
          type="text"
          placeholder="Name of Chef"
          required
          ref={chefInputRef}
          className={INPUT_STYLE}
        />
        <button
          type="submit"
          className="bg-yellow-500 text-gray-800 font-medium text-xl inline-flex  w-full items-center px-4 py-4 rounded-xl"
        >
          Add Now
        </button>
      </form>
    </div>
  );
};

export default NewMealForm;
Enter fullscreen mode Exit fullscreen mode

Save it, open the browser on http://localhost:3000/new-meal and add a new meal.

Add new meal

Big achievement here with the project, we can store data to a MongoDB database :)
Youuupiii

2. Conclusion

The Part 2 of our tutorial ends here. We basically worked on MongoDB database connection to our Food App, using the API Routes feature that comes with Next.js.

Warning: While practicing this tutorial, you might get this error => error - MongoNetworkError: connection 1 to 54.145.177.180:27017 closed. To avoid it, make sure that your computer IP address always match with the one you put on the MongoDB cluster in sub point 1.7

The final Part, part 3 will be published very soon, so again stay tuned and follow me on Twitter for updates.

Find the completed project here.

À bientôt

Oldest comments (1)

Collapse
 
8koi profile image
Hachikoi

Welp that was an unxepected & clever way to store images, good idea for improve further tnx!