Tips for creating a POST request using mongoose in NextJS version 13.4

Currently, I am faced with the challenge of executing a POST request using mongoose in NextJS. In my project structure, I have three key files: lib/dbConnect.js, models/User.js, and app/new/route.ts. As defined, app/new/route.ts is responsible for handling the form page where the POST request will be initiated. Let's take a closer look at my lib/dbConnect.js:

import mongoose from 'mongoose'

const MONGODB_URI = process.env.MONGODB_URI

if (!MONGODB_URI) {
  throw new Error(
    'Please define the MONGODB_URI environment variable inside .env.local'
  )
}

/**
 * To ensure connection persistence across hot reloads in development,
 * we utilize "Global" to maintain a cached connection.
 */
let cached = global.mongoose

if (!cached) {
  cached = global.mongoose = { conn: null, promise: null }
}

async function dbConnect() {
  if (cached.conn) {
    return cached.conn
  }

  if (!cached.promise) {
    const opts = {
      bufferCommands: false,
    }

    cached.promise = mongoose.connect(MONGODB_URI, opts).then((mongoose) => {
      return mongoose
    })
  }

  try {
    cached.conn = await cached.promise
  } catch (e) {
    cached.promise = null
    throw e
  }

  return cached.conn
}

export default dbConnect;

Moving on to models/User.js:

import mongoose from 'mongoose'

/* UserSchema maps to a designated collection in MongoDB database */
const UserSchema = new mongoose.Schema({
  name: {
    /* User's name */

    type: String,
    required: [true, 'Please provide your name.'],
    maxlength: [60, 'Name cannot exceed 60 characters'],
  },
  email: {
    /* User's email address */

    type: String,
    required: [true, "Please provide your email."],
    maxlength: [60, "Email cannot exceed 60 characters"],
  },
  password: {
    /* User's password */

    type: String,
    required: [true, 'Please provide your password.'],
    maxlength: [60, 'Password must not exceed 40 characters'],
  },
  // dob: {
  //   /* User's DOB */

  //   type: Date,
  //   required: true,
  // },
  country: {
    /* User's country */

    type: String,
    required: [true, 'Please provide your country.'],
    maxlength: [60, 'Country must not exceed 40 characters'],
  },
})

export default mongoose.models.User || mongoose.model('User', UserSchema)

Admittedly, I'm struggling with defining app/new/route.ts and implementing the POST request within it. Resources online haven't provided sufficient guidance. While some references mention middleware utilization, I've yet to decipher how to incorporate this into my existing dbConnect.js file.

Answer №1

Does your app/new/route.ts file resemble the following structure?

import User from "models/User.js";
import dbConnect from "lib/dbConnect.js";
import { NextRequest, NextResponse } from 'next/server';

dbConnect()

export async function POST(request: NextRequest) {
    try {
        const reqBody = await request.json()
        const { username, email, password } = reqBody

        const newUser = new User({
            username,
            email,
            password: hashedPassword
        })

        const savedUser = await newUser.save()

        return NextResponse.json({
            message: "User created successfully",
            sucess: true,
            savedUser
        }

    } catch(err) {

     console.log(err)
    }

}

If you are looking for an alternative to route.ts, consider leveraging NextJS's Server Actions for database requests. However, this approach may necessitate additional clarity on the client or server side integration.

An example of this concept could be implemented in a file like lib/user.action.ts:

import User from "models/User.js";
import dbConnect from "lib/dbConnect.js";

export async function updateUser() {

   dbConnect()

   try {
        await User.findOneAndUpdate(
            {
                email: email.toLowerCase(),
                name,
                password,
                country
            },
            { upsert: true }
        )

 
    } catch (error) {
        throw new Error(`Failed to create/update user: ${error.message}`)
    }

} 

Answer №2

My version of route.ts ended up being located in app/api/users/route.ts. Below is the code inside this file:

import { IncomingRequest, OutgoingResponse } from "next/server";
import dbConnect from '../../../lib/dbConnect'
import User from '../../../models/User'

export async function POST(req: IncomingRequest, res: OutgoingResponse) {
    const data = await req.json();
    await dbConnect();

    try {
        const user = await User.create(
            data
        ) /* creating a new model in the database */
        return OutgoingResponse.json({
            success: true,
            data: user,
            message: "Success"
        }, {
            status: 201,
        })
    } catch (error) {
        return OutgoingResponse.json({
            success: false,
            message: "Fail",
        }, {
            status: 400,
        })
    }
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Continuously receiving the "Add to home screen" prompt despite already installing the PWA app

Is there a method to determine if the Progressive Web App has already been installed? It is possible to cancel the prompt event in the 'beforeinstallprompt' event. window.addEventListener('beforeinstallprompt', (event) => { // co ...

What is the best practice for storing uploaded images or files in a MERN stack application?

I am currently in the process of working on a project. My tech stack includes node and express for the rest api, as well as next js for the front-end. Within my project, there is a form where users can add new products. The question that arises is: Where ...

Tips for concentrating on the initial input field produced by an ng-repeat in AngularJS

Currently, I am dynamically generating input fields using ng-repeat and everything is working smoothly. However, my requirement is to set focus on the first input that is generated by this ng-repeat based on their sequenceId values. So far, I have attempte ...

Issue encountered while configuring 'innerHTML' in xmlHttp.onreadystatechange function

Trying to create a JavaScript function that changes the innerHTML of a paragraph within an xmlHttp.onreadystatechange function, I encountered an error in the Chrome Console: Uncaught TypeError: Cannot set property 'innerHTML' of null at XMLH ...

Something is overriding the style created by makestyle material UI that I had implemented

How can I increase the importance of my makeStyles classes over default Material UI styles? Here is my code: import { createTheme, ThemeProvider } from '@mui/material/styles'; import { makeStyles, createStyles } from '@mui/styles'; co ...

Authenticate through navigation on an alternate component

I am in the process of developing a user interface that includes a side navigation and header bar. However, if the user is not logged in, I wish to redirect them to the login page. The primary component structure is as follows: class App extends Componen ...

Displaying Vue.js tooltips in a table when the text gets clipped

I'm currently facing an issue with creating a tooltip in my vue.js document. I attempted to follow this guide from https://www.w3schools.com/howto/tryit.asp?filename=tryhow_css_tooltip in order to create one, but it's not working as expected. Her ...

Add motion to the div element when hovering and moving the mouse away

Looking to add animation to a list moving from left to right and vice versa. Now, I want the list to animate from left to right when the mouse hovers over the div, and then animate from right to left when the mouse leaves the div. Can someone assist me wit ...

Converting JavaScript code from storeEval to executeScript_Sandbox in Selenium IDE using Kantu Ui.Vision

Looking for assistance with converting two snippets of Javascript code to extract date and time in a specific format, transitioning from storeEval to executeScript_Sandbox for use in Selenium Ide Kantu Ui.Vision. Due to recent updates, storeEval is now de ...

Ways to update the text alongside a slider form with JavaScript

I am currently working on a project using html and js function slide(){ let v= document.getElementById("slide_inner"); document.getElementById("slider").textContent=v.value; } <form id="slider"> <label for="slide_inner"&g ...

CSS Challenge: How to crop an image without using its parent container directly

I'm currently facing a complex CSS challenge that I can't seem to solve. I want to create an image controller (two-by-two layout on two lines) that can display: The top-left image in full size, The top-right with horizontal scrolling, The botto ...

Transforming Excel data into JSON format using ReactJS

Currently, I am in the process of converting an imported Excel file to JSON within ReactJS. While attempting to achieve this task, I have encountered some challenges using the npm XLSX package to convert the Excel data into the required JSON format. Any as ...

Which is the better option: utilizing the submit event of the form, or incorporating ajax functionality?

Forms are an essential part of my website design, and I often find myself contemplating whether it's better to submit a form using a standard submit button or utilizing Ajax. Typically, I opt for Ajax to prevent the dreaded issue of form re-submission ...

Having trouble with Lerna bootstrap? You might be running into the dreaded npm error code E401

Every time I run Lerna bootstrap on Jenkins, it fails with an error, but it works fine on my local machine. npm ERR! code E401 npm ERR! Unable to authenticate, need: BASIC realm="Sonatype Nexus Repository Manager" Package.json in the main folder ...

Troubleshooting issue: JSON object is returning undefined despite its presence in NASA API integration with ReactJS

{this.imageRenderer(item.data[0].media_type, item.links[1], item.links[0])} When trying to access item.links, it shows as undefined even though it is present. (Data is retrieved from NASA API) Image: As seen above, the links attribute exists. I am puzzle ...

Using Q to conduct polling asynchronously with promises

I am facing a situation similar to the one discussed in this blog post: Polling with promises. The author explains using promises for polling until a JobID is returned. I intend to implement this using Q. I want to chain promises together but my attempts ...

Function used to update database through AJAX technology

I have implemented a PHP script to update my database using AJAX, and it is working correctly after being tested. To pass the required two variables to the PHP script for updating the database, I created a JavaScript function that utilizes AJAX to call the ...

Rendering based on conditions with a pair of values

I am trying to render my component only if the id is equal to either 15 or 12. My current approach is not working as expected, it only renders the component when I check for one id at a time, but I need to check for both. {query_estate_id === 15 || q ...

Obtaining JSON data from a PHP script using AngularJS

I've been exploring an AngularJS tutorial on a popular website called w3schools. Check out the tutorial on w3schools After following the tutorial, I modified the script to work with one of my PHP scripts: <!DOCTYPE html> <html > <sty ...

Preventing Broken URLs in Jquery each

What is the best way to prevent taking images with broken URLs? jQuery.each(jQuery('img'), function(index, obj) { imageStack.add(jQuery(obj)); }); ...