Reputation: 610
I connected my NextJs
app with MongoDB Atlas
. It is working fine on localhost but it doesn't work on Production hosted on Vercel
.
At first, I thought it's about network access and added 0.0.0.0/0 on the IP Access List
but no difference. The error 500
is only being shown on the production.
I have called the nextjs's api from Formik's form submit. On console, I also see this Error at onSubmit (test-2b8b0b9f0ee833a8.js:1:14850)
The codes for connect and disconnect
import mongoose from 'mongoose';
const connection = {};
async function connect() {
if (connection.isConnected) {
console.log('already connected');
return;
}
if (mongoose.connections.length > 0) {
connection.isConnected = mongoose.connections[0].readyState;
if (connection.isConnected === 1) {
console.log('use previous connection');
return;
}
await mongoose.disconnect();
}
const db = mongoose.connect(process.env.MONGODB_URI);
console.log('new connection');
connection.isConnected = db.connections[0].readyState;
}
async function disconnect() {
if (connection.isConnected) {
if (process.env.NODE_ENV === 'production') {
await mongoose.disconnect();
connection.isConnected = false;
} else {
console.log('not disconnected');
}
}
}
function convertDocToObj(doc) {
doc._id = doc._id.toString();
doc.createdAt = doc.createdAt.toString();
doc.updatedAt = doc.updatedAt.toString();
return doc;
}
const db = { connect, disconnect, convertDocToObj };
export default db;
Person Model
import mongoose from 'mongoose';
const PersonSchema = new mongoose.Schema(
{
name: { type: String, required: true },
count: { type: Number, required: false },
},
{
timestamps: true,
}
);
const Person = mongoose.models.Person || mongoose.model('Person', PersonSchema);
export default Person;
pages/api/my-endpoint.js
import db from '../../../mongoose/db';
import Person from '../../../mongoose/models/Person';
const handler = async (req, res) => {
// the codes
await db.connect();
let person = await Person.findOne({
name: 'Frank',
});
person.count += 1;
await type.save();
await db.disconnect();
// the codes
}
Upvotes: 0
Views: 982
Reputation: 121
The way that I'm doing you can also try or modify --
/lib/dbConnect.js
import mongoose from 'mongoose'
const DB_URL = process.env.DB_URL
if (!DB_URL) {
throw new Error(
'Please define the DB_URL environment variable inside .env.local'
)
}
/**
* Global is used here to maintain a cached connection across hot reloads
* in development. This prevents connections growing exponentially
* during API Route usage.
*/
let cached = global.mongoose
if (!cached) {
cached = global.mongoose = { conn: null, promise: null }
}
async function dbConnect() {
if (cached.conn) {
console.log("--- db connected ---");
return cached.conn
}
if (!cached.promise) {
const opts = {
bufferCommands: false,
}
cached.promise = mongoose.connect(DB_URL, opts).then((mongoose) => {
console.log("--- db connected ---")
return mongoose
})
}
cached.conn = await cached.promise
console.log("--- db connected ---")
return cached.conn
}
export default dbConnect;
/models/videos.js
import mongoose from "mongoose";
let videoSchema = mongoose.Schema({
videoID: {
type: String,
},
authorID: {
type: String,
required: true,
},
authorName: {
type: String,
required: true,
},
videoURL: {
type: String,
required: true,
}
});
const Videos =mongoose.models?.videos || mongoose.model("videos", videoSchema);
export default Videos;
/pages/api/getVideos.js
import dbConnect from "../../lib/dbConnect";
import Videos from "../../models/videos";
export default async function handler(req,res){
try{
await dbConnect();
await Videos.find().lean().then(response=>{
return res.status(200).json(response);
});
}catch(e){
res.status(400).json(e);
}
}
//api calling method
export const fetcher = (url,method,payload) =>
fetch(url,{
method:method,
headers:{
Accept:'application/json',
'Content-Type':"application/json"
},
body:JSON.stringify(payload)
}).then(res=>{
if(!res.ok){
const error = new Error("Error while fetching the data");
error.status = res.ok
error.message = 'error'
return error;
}else{
return res.json();
}
})
Upvotes: 0