I was wondering if anyone could help me with figuring out why I'm getting this error.
Route.post() requires a callback function but got a [object Undefined]
I'm trying to insert a row into a database with node/express. This is all new concepts to me and so it's likely that I'm missing something somewhat obvious here?
connect.js
const {Client} = require('pg');
const client = new Client({
connectionString: process.env.DATABASE_URL,
ssl: {
rejectUnauthorized: false,
}
});
const createSpellTable = `
CREATE TABLE spells (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
topic TEXT NOT NULL,
date TEXT NOT NULL
)
`;
client.query(createSpellTable, (err, res) => {
if(err){
console.log(`Error creating table: ${err.message}`);
}else{
console.log('Table created');
}
});
const createOrderLuminos = `
CREATE TABLE orderluminos (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
orderId TEXT NOT NULL
)
`;
client.query(createOrderLuminos, (err, res) => {
if(err){
console.log(`Error creating table: ${err.message}`);
}else{
console.log('Table created');
}
});
exports.storeSpellData = (req, res, next) => {
const query = `
INSERT INTO spells (name, topic, date)
VALUES ($1, $2, $3)
`;
const values = [req.body.quickSpellsName, req.body.quickSpellsTopic, req.body.quickSpellsDate];
client.query(query, values, (err, res) => {
if(err){
console.log(`Error inserting data: ${err.message}`);
res.status(500).send({ error: 'Error inserting data' });
}else{
console.log(res.rows);
next();
}
});
client.end();
};
module.exports = {client};
app.js
const express = require('express');
const path = require('path');
const bodyParser = require('body-parser');
const database = require('./database/connect');
const app = express();
app.set('view engine', 'ejs');
const homeRoute = require('./routes/index');
const submitRoute = require('./routes/submit');
app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());
app.use(express.static(path.join(__dirname, 'public')));
app.use(homeRoute);
app.use(submitRoute);
app.listen(process.env.PORT || 3000, function () {
console.log("Express server listening on port %d in %s mode", this.address().port, app.settings.env);
});
database.client.connect();
controllers/submits.js
exports.getQuickSpells = (req, res, next) => {
res.render('quick-spells', {
path: '/quick-spells',
pageTitle: 'Quick Spells'
});
};
exports.postQuickSpells = (req, res, next) => {
res.render('quick-spells', {
path: '/quick-spells',
quickSpellsName: req.body.quickSpellsName,
quickSpellsTopic: req.body.quickSpellsTopic,
quickSpellsDate: req.body.quickSpellsDate,
pageTitle: 'Quick Spells'
});
};
exports.getOrderLuminos = (req, res, next) => {
res.render('order-luminos', {
path: '/order-luminos',
pageTitle: 'Order Luminos'
});
};
exports.postOrderLuminos = (req, res, next) => {
res.render('order-luminos', {
path: '/order-luminos',
orderNumber: req.body.orderNumber,
pageTitle: 'Order Luminos'
});
};
routes/submit.js
const express = require('express');
const db = require('../database/connect');
const submits = require('../controllers/submits');
const router = express.Router();
router.get('/quick-spells', submits.getQuickSpells);
router.post('/quick-spells', db.storeSpellData, submits.postQuickSpells);
router.get('/order-luminos', submits.getOrderLuminos);
router.post('/order-luminos', submits.postOrderLuminos);
module.exports = router;
I've tried setting up my router.post to look like this:
router.post('/quick-spells', function (req, res, next){
db.storeSpellData
submits.postQuickSpells
});
and this omitted the error but when I try to send the form data it freezes in limbo forever.
Edit:
Here's the error log from the console
/node_modules/express/lib/router/route.js:211
throw new Error(msg);
^
Error: Route.post() requires a callback function but got a [object Undefined]
at Route.<computed> [as post] (/node_modules/express/lib/router/route.js:211:15)
at proto.<computed> [as post] (/node_modules/express/lib/router/index.js:521:19)
at Object.<anonymous> (/routes/submit.js:9:8)
at Module._compile (node:internal/modules/cjs/loader:1105:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1159:10)
at Module.load (node:internal/modules/cjs/loader:981:32)
at Module._load (node:internal/modules/cjs/loader:827:12)
at Module.require (node:internal/modules/cjs/loader:1005:19)
at require (node:internal/modules/cjs/helpers:102:18)
at Object.<anonymous> (/app.js:13:21)
Line 13 in app.js
const submitRoute = require('./routes/submit');
CodePudding user response:
The solution commented on by Pointy is correct.
Storing my storeSpellData
function in a variable instead of exporting it directly like so:
const storeSpellData = (req, res, next) => {
const query = `
INSERT INTO spells (name, topic, date)
VALUES ($1, $2, $3)
`;
const values = [req.body.quickSpellsName, req.body.quickSpellsTopic, req.body.quickSpellsDate];
client.query(query, values, (err, res) => {
if (err) {
console.log(`Error inserting data: ${err.message}`);
} else {
console.log(res.rows);
next();
}
});
client.end();
};
and then just include it in the export below:
module.exports = { client, storeSpellData };