Hi Everyone,
I hope you are well!
At this point of my nodejs, express and mongoose app I have fairly simple routes, views, models and controllers. I have a story_points_create_post route that when called from Postman does call the code. I’ve been able to trace (using a debugger) that the model.save does not save and never returns a response to resolve the post.
Hrere is the story_points_create_post route in project/routes:
import express from 'express';
const router = express.Router();
import {story_point_get, story_points_create_post,
index, story_points_delete_post} from '../controllers/story_point_controller.js'
router.get("/", index)
.get(
"/story_points/create",
story_point_get
)
// POST request for creating Story Points.
.post(
"/story_points/create",
story_points_create_post
)
// POST request to delete story points.
.post(
"/story_points/:id/delete",
story_points_delete_post
);
export {router as catalogRouter};
Here is the controller:
export const story_points_create_post = async (req, res) => {
console.log('made it within the post route')
console.log(req.body)
let storyPoints = new StoryPoints({
firstName: req.body.firstName,
lastName: req.body.lastName,
team: req.body.team,
storyPoints: req.body.storyPoints,
sprint: {
name: req.body.sprint.name,
startDate: req.body.sprint.startDate,
endDate: req.body.sprint.endDate
}
})
try {
res.send(await storyPoints.save())
} catch(e) {
console.log(e)
}
};
Notice the try/catch block with res.send(await storyPoints.save()) this never resolves. I did comment this out and returned the storyPoints model res.send(storyPoints) and got the model looking correct with all required fields present, here was the output:
{
"firstName": "Joe",
"lastName": "Smoe",
"team": "Data Science",
"storyPoints": 3,
"sprint": {
"name": "My first Sprint",
"startDate": "2023-10-18T20:23:23.000Z",
"endDate": "2023-10-18T20:24:09.000Z"
},
"_id": "6540057560a4fde45b3cc521"
}
The call to mode.save() eventually times out with a 500 error however it is not caught by the try/catch ( maybe do the async call?
In atlas right now here are some example document:
{"_id":{"$oid":"6531798a38ae95fe7e56c3cc"},"firstName":"Joe","lastName":"Smoe","team":"Data Science","storyPoints":{"$numberInt":"15"},"sprint":{"name":"My first Sprint","startDate":{"$date":{"$numberLong":"1697660603000"}},"endDate":{"$date":{"$numberLong":"1697660649000"}}},"createdAt":{"$date":{"$numberLong":"1697741194091"}},"updatedAt":{"$date":{"$numberLong":"1697741194091"}},"__v":{"$numberInt":"0"}}
Here is the storyPoint model:
/ Require Mongoose
import mongoose from "mongoose";
// Define a schema
const Schema = mongoose.Schema;
/**
* Story Point Report Schema
* The timestamps used in this way create updatedAt and createdAt automatically
*/
const storyPointsSchema = new Schema({
firstName: {
required: true,
type: String,
maxLength: 100
},
lastName: {
required: true,
type: String,
maxLength: 100
},
team: {
required: true,
type: String}
,
storyPoints: {
required: true,
type: Number
},
sprint: {
name: {
required: true,
type: String
},
startDate: {
required: true,
type: Date,
},
endDate: {
required: true,
type: Date,
}
}
}, {timestamps: true });
storyPointsSchema.pre('save', function(next){
this.spintStartDate = Date.now();
this.sprintEndDate = Date.now() + 14;
})
/**
* Calculate Full Name
* Virtual for ticket assignee's full name
*/
storyPointsSchema.virtual('name').get(() => {
let fullname = ""
if (this.firstName && this.lastName) {
fullname = `${this.firstName}, ${this.lastName}`
}
return fullname
})
function convertDateToReadableFormat(Date) {
return DateTime.formJSDate(Date).toLocaleString(DateTime.DATE_MED);
}
storyPointsSchema.virtual('prety_dates').get(() => {
return {
sprintStartDateF: convertDateToReadableFormat(this.spintStartDate),
sprintEndDateF: convertDateToReadableFormat(this.spintEndDate),
updatedAtF: convertDateToReadableFormat(this.updatedAt)
}
})
export const StoryPoints = mongoose.model('StoryPoints', storyPointsSchema)
Here is the atlas db connection which when the app is running reports Connected to MongoDB:
import mongoose from 'mongoose';
import * as dotenv from 'dotenv';
dotenv.config()
// Set `strictQuery: false` to globally opt into filtering by properties that aren't in the schema
// Included because it removes preparatory warnings for Mongoose 7.
// See: https://mongoosejs.com/docs/migrating_to_6.html#strictquery-is-removed-and-replaced-by-strict
mongoose.set("strictQuery", false);
const mongoDBConnect = async () => {
try {
await mongoose.connect(process.env.DATABASE_URI, {
useNewUrlParser: true,
useUnifiedTopology: true
});
console.log('Connected to MongoDB');
return 'Connected to MongoDB'
} catch (error) {
console.log('Error connecting to MongoDB:', error);
return JSON.stringify(`Error connecting to MongoDB: ${error}`)
}
};
export const connectDB = mongoDBConnect;
And finally here is the app:
import createError from 'http-errors';
import express from 'express';
import bodyParser from 'body-parser';
import * as path from 'path';
import { dirname } from 'path';
import { fileURLToPath } from 'url';
import cookieParser from 'cookie-parser';
import logger from 'morgan';
/**
* Database - MongoDB using Mongoose ORM
*/
import {connectDB} from './datatabase/db.js'
// Connect to MongoDB
connectDB();
import {indexRouter} from './routes/index.js';
import {storyPointsRouter} from './routes/metrics.js';
import {catalogRouter} from './routes/catalog.js';
const __dirname = dirname(fileURLToPath(import.meta.url));
export const app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
app.use('/storyPoints', storyPointsRouter)
app.use('/metrics', catalogRouter)
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
Can you see any issues with the code or reasons why save() is failing?
Your help is appreciated.