Mongoose + Middleware: Cannot read properties of undefined
Unanswered
Spectacled bear posted this in #help-forum
Spectacled bearOP
Using Next.js 14 app router with mongoose, I encounter this error as soon as I import a server action into my middleware:
The root of the issue seems to be that [middleware in Next.js is an edge runtime and DB connections aren't recommended in there](https://nextjs-forum.com/post/1142075909856305162#message-1142087679559860244).
Why isn't it possible to connect to a DB in Next.js middleware? And what's the alternative?
### (Temporary) solution
I've solved the problem temporarily by moving
But this is indeed only a temporary fix, because sooner or later the
⨯ src\models\nachricht.ts (38:0) @ <unknown>
⨯ Cannot read properties of undefined (reading 'Message')
36 | );
37 |
> 38 | export default mongoose.models.Message || mongoose.model('Message', messageSchema)The root of the issue seems to be that [middleware in Next.js is an edge runtime and DB connections aren't recommended in there](https://nextjs-forum.com/post/1142075909856305162#message-1142087679559860244).
Why isn't it possible to connect to a DB in Next.js middleware? And what's the alternative?
### (Temporary) solution
I've solved the problem temporarily by moving
saveMessage() to a seperate file for server actions which establish database connection and use models.But this is indeed only a temporary fix, because sooner or later the
getUniqueCityNamesAndSlugs() action will also work with a database connection (instead of a JSON file).1 Reply
Spectacled bearOP
## File Structure/Code during bug
src/models/nachricht.ts:
src/lib/db.ts:
src/app/actions.ts:
src/middleware.js:
src/models/nachricht.ts:
import mongoose from "mongoose";
const { Schema } = mongoose;
const messageSchema = new Schema(
// ...
);
export default mongoose.models.Message || mongoose.model('Message', messageSchema)src/lib/db.ts:
import mongoose from "mongoose";
const connect = async () => {
if(mongoose.connections[0].readyState) {
console.log('Mongoose already connected')
return
};
try {
console.log('MONGODB_URI', process.env.MONGODB_URI)
await mongoose.connect(process.env.MONGODB_URI)
console.log('Mongoose connected')
} catch (error) {
console.error('error:', error)
}
}
export default connect;src/app/actions.ts:
'use server'
import hpOrgDb from "@/lib/hpOrgDb.json"
import connect from "@/lib/db"
import nachricht from "@/models/nachricht"
// ...
export async function getUniqueCityNamesAndSlugs(){
// ...getting a list of all cities in the DB (currently just using a JSON file)
}
export async function saveMessage(prevState, formData){
await connect()
try {
await nachricht.create({
// formData
})
} catch (error) {
// ...error catching
return newState
}
return newState
}src/middleware.js:
import { NextResponse } from 'next/server'
import { getUniqueCityNamesAndSlugs } from '@/app/actions' // <=== ISSUE HERE!?
export async function middleware(request) {
if (request.nextUrl.pathname.includes("/doc-")) {
// ...
const uniqueCityNamesAndSlugs = await getUniqueCityNamesAndSlugs()
// ...
return NextResponse.rewrite(new URL(`/doc/${cityName}`, request.url))
}
}