I have just started to use next.js and whenever I call api which has reference to another document, mongoose throws an error to me stating that "Schema hasn't been registered for model".
Here is my code.
Models
Task.js
const mongoose = require("mongoose");
const TaskModel = () => {
const schema = mongoose.Schema;
const taskSchema = new schema(
{
taskName: {
type: String,
required: true,
},
empId: {
type: schema.Types.ObjectId,
ref: "Employee",
required: true,
},
adminId: {
type: schema.Types.ObjectId,
ref: "Admin",
required: true,
},
deptId: {
type: schema.Types.ObjectId,
ref: "Department",
required: true,
},
deadline: {
type: String,
},
status: {
type: Boolean,
default: false,
},
completedDate: {
type: String,
default: "",
},
completionStatus: {
type: String,
default: "Assigned",
},
},
{ timestamps: true }
);
return mongoose.models.Task ?? mongoose.model("Task", taskSchema);
};
export default TaskModel;
employee.js
const mongoose = require("mongoose");
const EmployeeModel = () => {
const schema = mongoose.Schema;
const employeeSchema = new schema({
empName: {
type: String,
required: true,
},
empEmail: {
type: String,
required: true,
},
password: {
type: String,
required: true,
},
department: {
type: schema.Types.ObjectId,
ref: "Department",
required: true,
// type:String
},
document: {
type: String,
},
loginStatus: {
type: Boolean,
default: false,
},
});
return mongoose.models.Employee ?? mongoose.model("Employee", employeeSchema);
};
export default EmployeeModel;
db.js (For connecting the app with mongoDB)
import mongoose from "mongoose";
import TestModel from "@/models/test";
import TaskModel from "@/models/task";
import AdminModel from "@/models/admin";
import EmployeeModel from "@/models/employee";
import DepartmentModel from "@/models/department";
if (mongoose.connection.readyState !== 1) {
mongoose.connect(process.env.MONGO_URI);
}
mongoose.Promise = global.Promise;
export const db = {
Test: TestModel,
Task: TaskModel,
Admin: AdminModel,
Employee: EmployeeModel,
Department: DepartmentModel,
};
getTask/route.jsx
import { db } from "@/helpers/db";
const Task = db.Task();
export const GET = async () => {
try {
const result = await Task.find().populate("empId");
return Response.json(result);
} catch (error) {
console.log(error);
return Response.json(error, { status: 422 });
}
};
dashboard/page.jsx
"use client";
import style from "./page.module.css";
import Api from "./api";
import { useState, useEffect } from "react";
const Dashboard = () => {
const [filterData, setFilterData] = useState("");
const [finalData, setFinalData] = useState([]);
useEffect(() => {
const apiCall = async () => {
const taskdata = await fetch("http://localhost:3000/api/task/getTask");
const actualTaskData = await taskdata.json();
console.log(actualTaskData);
return actualTaskData;
};
const apires = apiCall();
setFinalData(apires);
}, []);
return (
<div style={{ margin: 0, padding: 0 }}>
</div>
);
};
export default Dashboard;
I am attaching the folder structure for reference
It looks like you will have to register the Employee
model to use it in the populate
method. This is untested but try:
const Task = db.Task();
const Employee = db.Employee(); //< Instantiate an Employee model
export const GET = async () => {
try {
const result = await Task.find().populate({ path: "empId", model: Employee });//< Explicitly use the Employee model here
return Response.json(result);
} catch (error) {
console.log(error);
return Response.json(error, { status: 422 });
}
};