javascriptnode.jsexpressexpress-router

Error: Route.post() requires a callback function but got a [object Undefined] in server.js


I'm currently setting up a nodeJS server using express. I have two backend files, one is called account.js in a folder called routes and the other is called server.js. I cant get it to run because its complaining that Error: Route.post() requires a callback function but got a [object Undefined], specifically in const accountRoutes = require('./routes/account'); app.use('/account', accountRoutes); (see in code down below:)

server.js

// Import necessary modules: express, http server, socket.io, pg, cors, dotenv, fs
const cors = require('cors');
const dotenv = require('dotenv');
const express = require('express');
const { createServer } = require('http');
const { join } = require('path');
const fs = require('fs');
const { Pool } = require('pg');
const bodyParser = require('body-parser');
const jwt = require('jsonwebtoken');


// Initialize Express application
const app = express();
// Define saltRounds for bcrypt hashing
const saltRounds = 10;
app.use(cors());
const server = createServer(app);
const io = require('socket.io')(server, {
  cors: {
    origin: "http://localhost:3000",
    methods: ["GET", "POST"],
    transports: ['websocket', 'polling'],
    allowedHeaders: ['Access-Control-Allow-Origin'],
    credentials: true
  },
  allowEIO3: true,
  cookie: {
    name: "io",
    path: "/",
    httpOnly: true,
    sameSite: "lax"
  }
});
io.attach(server);
server.listen(3000, () => {
  console.log('server running at http://localhost:3000');
});


const dbConfig = JSON.parse(fs.readFileSync('db_config.json'));
dotenv.config();
const pool = new Pool(dbConfig);

const JWT_SECRET = process.env.JWT_SECRET;

// Make `pool` available to other parts of the application
module.exports = pool;

// Store session IDs
const accounts = {};

// Middleware to parse request bodies
app.use(bodyParser.urlencoded({ extended: true }));
// Serve static files from the 'public' directory
app.use(express.static('public'));
const accountRoutes = require('./routes/account');
app.use('/account', accountRoutes);

// JWT Middleware
const authenticateToken = (req, res, next) => {
  var token = req.headers.authorization.split(' ')[1];
  if (token) {
    return jwt.verify(token, JWT_SECRET, function (err, decoded) {
      if (err) {
        return res.json({
          success: false,
          message: "Failed to authenticate token.",
        });
      }
      req.user = decoded;
      return next();
    });
  }
  return res.unauthorized();
};

// Serve index.html when root URL is accessed
app.get('/', (req, res, next) => {
  res.sendFile(join(__dirname + '/public/index.html'));
});


app.get('/auth', authenticateToken, (req, res) => {
  res.json({ authenticated: true, user: req.user });
});


app.post('/', async (req, res) => {});


module.exports = { authenticateToken, pool, JWT_SECRET, saltRounds };

account.js

const {authenticateToken, pool, JWT_SECRET, saltRounds } = require('../server.js');
const bcrypt = require('bcrypt');
const jwt = require('jsonwebtoken');
const express = require('express');
const router = express.Router();

// Handle POST request to /logout route
router.post('/logout', authenticateToken, async (req, res) => {
......
});

// Handle POST request to /register route
router.post('/register', async (req, res) => {
.......
});

// Handle POST request to /login route
router.post('/login', async (req, res) => {
.......
});

// Handle POST request to /delete route
router.post('/delete', authenticateToken, async (req, res) => {
.......
});

module.exports = router;

I tried to export the modules correctly and import them again, but it isnt working.


Solution

  • You are importing server.js into account.js and then importing account.js into server.js which creates a Circular-Dependency

    Circular-Dependencies occur when two or more modules depend on each other, directly or indirectly, creating a loop. In you case this has happened.

    Solutions

    1. You should create a separate module for authenticateToken, pool, JWT_SECRET, saltRounds and then import it into account.js.