I'm using Mongoose with Next.js, atm I'm trying to initially seed the database by hitting the localhost:3000/api/seed
endpoint, but I'm getting an error. Insomnia gives me a 500 Internal Server Error
. This is the output in the terminal in VSCode:
error - CastError: Cast to string failed for value "[ 'pending', 'in-progress', 'finished' ]" (type Array) at path "status"
at SchemaString.cast (C:\TMP\_coding-important\03-open-jira\node_modules\mongoose\lib\schema\string.js:603:11)
at SchemaString.enum (C:\TMP\_coding-important\03-open-jira\node_modules\mongoose\lib\schema\string.js:238:33)
at SchemaString.SchemaType (C:\TMP\_coding-important\03-open-jira\node_modules\mongoose\lib\schematype.js:115:18)
at new SchemaString (C:\TMP\_coding-important\03-open-jira\node_modules\mongoose\lib\schema\string.js:28:14)
at Schema.interpretAsType (C:\TMP\_coding-important\03-open-jira\node_modules\mongoose\lib\schema.js:1274:22)
at Schema.path (C:\TMP\_coding-important\03-open-jira\node_modules\mongoose\lib\schema.js:900:27)
at Schema.add (C:\TMP\_coding-important\03-open-jira\node_modules\mongoose\lib\schema.js:654:14)
at new Schema (C:\TMP\_coding-important\03-open-jira\node_modules\mongoose\lib\schema.js:133:10)
at eval (webpack-internal:///(api)/./models/Entry.ts:8:21)
at Object.(api)/./models/Entry.ts (C:\TMP\_coding-important\03-open-jira\.next\server\pages\api\seed.js:62:1) {
stringValue: `"[ 'pending', 'in-progress', 'finished' ]"`,
messageFormat: undefined,
kind: 'string',
value: [ 'pending', 'in-progress', 'finished' ],
path: 'status',
reason: null,
valueType: 'Array'
This is my code: ...
model/Entry.ts
import mongoose, { Model, Schema } from "mongoose";
import { Entry } from "../interfaces";
interface IEntry extends Entry {}
const entrySchema = new Schema({
description: { type: String, required: true },
createdAt: { type: Number },
status: {
type: String,
enum: {
value: ["pending", "in-progress", "finished"],
message: "{VALUE} is not an allowed state",
},
},
});
const EntryModel: Model<IEntry> = mongoose.models.Entry || mongoose.model("Entry", entrySchema);
export default EntryModel;
database/seed-data.ts
interface SeedData {
entries: SeedEntry[];
}
interface SeedEntry {
description: string;
status: string;
createdAt: number;
}
export const seedData: SeedData = {
entries: [
{
description:
"pending: Lorem ipsum dolor, sit amet consectetur adipisicing elit. Iusto inventore accusamus nulla harum?",
status: "pending",
createdAt: Date.now(),
},
{
description:
"in-progress: Lorem ipsum dolor sit amet consectetur adipisicing elit. Enim quam illo eligendi id.",
status: "in-progress",
createdAt: Date.now() - 1000000,
},
{
description:
"finished: Lorem ipsum dolor sit amet consectetur adipisicing elit. Aliquam quos necessitatibus distinctio repellendus.",
status: "finished",
createdAt: Date.now() - 100000,
},
],
};
pages/api/seed.ts
import type { NextApiRequest, NextApiResponse } from "next";
import { db } from "../../database";
import { seedData } from "../../database/seed-data";
import { Entry } from "../../models";
type Data = {
message: string;
};
export default async function handler(req: NextApiRequest, res: NextApiResponse<Data>) {
if (process.env.NODE_ENV == "production") {
return res.status(401).json({ message: "Access to service not allowed" });
}
await db.connect();
await Entry.deleteMany();
await Entry.insertMany(seedData.entries)
await db.disconnect();
res.status(200).json({ message: "Process executed successfully" });
}
I've tried looking up the issue and in most cases it involves how the property enum
is used incorrectly when defining the type in the schema...
However, I'm pretty new to this and haven't got a clue how to proceed XD Hence why I'm posting here.
CodePudding user response:
I am not that good in Typescript. You can create a enum and assign it to the schema and use this enum also for the document.
export enum Status {
PENDING = 'pending',
IN_PROGRESS = 'in-progress',
FINISHED = 'finished'
}
const entrySchema = new Schema({
description: { type: String, required: true },
createdAt: { type: Number },
status: {
type: String,
enum: Status,
default: Status.PENDING
},
});
interface SeedData {
entries: SeedEntry[];
}
interface SeedEntry {
description: string;
status: string;
createdAt: number;
}
export const seedData: SeedData = {
entries: [
{
description:
"pending: Lorem ipsum dolor, sit amet consectetur adipisicing elit. Iusto inventore accusamus nulla harum?",
status: Status.PENDING,
createdAt: Date.now(),
},
{
description:
"in-progress: Lorem ipsum dolor sit amet consectetur adipisicing elit. Enim quam illo eligendi id.",
status: Status.IN_PROGRESS,
createdAt: Date.now() - 1000000,
},
{
description:
"finished: Lorem ipsum dolor sit amet consectetur adipisicing elit. Aliquam quos necessitatibus distinctio repellendus.",
status: Status.FINISHED,
createdAt: Date.now() - 100000,
},
],
};
CodePudding user response:
Following the same line of code, with much more time for looking up the cause of my mistake, I found out that I was missing something.
When setting up the enum
, I set up the property value
, when it should have been values
:
enum: {
value: ["pending", "in-progress", "finished"],
message: "{VALUE} is not an allowed state",
},
Though this is the most precise answer because it actually addresses the error in my OP, I marked ratzownal's answer as the best one since it also worked and he was so quick to respond. Credit where credit is due.
I'm simply adding this for future reference.