Search code examples
mysqlnode.jsexpresssequelize-cli

node server not returning any response after API request


I am building an API with Node.js, Express, MYSQL and with the help of sequelize. I am using MVC pattern.

The problem I am encountering however is the server cannot send back any http response after request. When sending a post request for example with postman, the request keeps on loading and will terminate after around 2 minutes with COULD NOT GET ANY RESPONSE exception. While this is happening, data is correctly saved in the database.

This is my AuthController user registration method:

'use strict';
// AuthController.js
var express = require('express');
var router = express.Router();
var bodyParser = require('body-parser');
router.use(bodyParser.urlencoded({ extended: false }));
router.use(bodyParser.json());
var jwt = require('jsonwebtoken');
var bcrypt = require('bcryptjs');
const Model = require('../models/index');
const User = Model.sequelize.import('../models/user');


// Register new User.
exports.register = function(req, res) {
        var hashedPassword = bcrypt.hashSync(req.body.password, 8);

     User.create({
     name : req.body.name,
    email : req.body.email,
    password : hashedPassword
        }, 

function (err, user) {
    if (err) 
    {
      return res.status(500).send("There was a problem registering the user. "+err)
    }
    else{
      // create a token
    var token = jwt.sign({ id: user._id }, process.env.AUTH0_CLIENT_SECRET, {
      expiresIn: 86400 // expires in 24 hours
    });
    res.status(200).json({ auth: true, token: token }); 
    }



  }); 

};

// App.js

var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
const cors = require('cors');
var app = express();
var indexRoutes = require('./routes/index');
var userRoutes = require('./routes/users');
var courseRoutes = require('./routes/courses');
var authRoutes = require('./routes/auth');

// view engine setup
// Currently I am not using view-templates
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(cors());
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));

app.use(cookieParser());
app.use(cors()); //enable CORS
app.use(express.static(path.join(__dirname, 'public')));

//User Routes
app.use('/', indexRoutes);
app.use('/api', userRoutes);
app.use('/api', courseRoutes);
app.use('/api/auth', authRoutes);

// 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');
});

module.exports = app;

//ROUTES

//auth.js

var express = require('express');
var router = express.Router();
//Require Controller Modules
var controller = require('../controllers/AuthController');

//Register new user

router.post('/register', controller.register);
router.get('/user', controller.me);

router.post('/login', controller.login);
router.get('/logout', controller.logout);


module.exports = router;

//User Model

'use strict';
module.exports = (sequelize, DataTypes) => {
  var User = sequelize.define('User', {
    //id: DataTypes.INTEGER,
    name: DataTypes.STRING,
    email: {type: DataTypes.STRING, allowNull: false, unique: true, validate: { isEmail: {msg: "Invalid Email"} }},
    password: DataTypes.STRING
  }, {});
  User.associate = function(models) {
    // associations can be defined here

  };
  return User;
};

DB Connection //in models/index.js

'use strict';

var fs        = require('fs');
var path      = require('path');
var Sequelize = require('sequelize');
var basename  = path.basename(__filename);
var env       = process.env.NODE_ENV || 'development';
var config = require(__dirname + '/../config/config.json')[env];
var db        = {};
const Op = Sequelize.Op;

if (config.use_env_variable) {
  var sequelize = new Sequelize(process.env[config.use_env_variable], config);
} else {

  var sequelize = new Sequelize(config.database,
   config.username,
    config.password, 

     { 
  host: config.host,
  dialect: config.dialect,
  operatorsAliases: false, 
    }
  );


  //check if connection is established
  sequelize
  .authenticate()
  .then(() => {
    console.log('Database Connection has been established successfully.');
  })
  .catch(err => {
    console.error('Unable to connect to the database:', err);
  });
}

fs
  .readdirSync(__dirname)
  .filter(file => {
    return (file.indexOf('.') !== 0) && (file !== basename) && (file.slice(-3) === '.js');
  })
  .forEach(file => {
    var model = sequelize['import'](path.join(__dirname, file));
    db[model.name] = model;
  });

Object.keys(db).forEach(modelName => {
  if (db[modelName].associate) {
    db[modelName].associate(db);
  }
});

db.sequelize = sequelize;
db.Sequelize = Sequelize;

module.exports = db;

I think there is something wrong I am committing or missing out something. I am experiencing this problem when sending POST REQUESTS. Data is saved in mysql table but no response is sent back.

Please assist. Thanks.


Solution

  • Thank you guys for trying to assist. After working around I discovered that problem was with the controller method. The way it was structured was not sending back response after data is persisted in the database. This is how I recoded my register method in AuthController:

    //Old one

    // Register new User.
    exports.register = function(req, res) {
            var hashedPassword = bcrypt.hashSync(req.body.password, 8);
    
         User.create({
         name : req.body.name,
        email : req.body.email,
        password : hashedPassword
            }, 
    
    function (err, user) {
        if (err) 
        {
          return res.status(500).send("There was a problem registering the user. "+err)
        }
        else{
          // create a token
        var token = jwt.sign({ id: user._id }, process.env.AUTH0_CLIENT_SECRET, {
          expiresIn: 86400 // expires in 24 hours
        });
        res.status(200).json({ auth: true, token: token }); 
        }
    

    //Rewrite:

    // Register new User.
    exports.register = function(req, res) {
            var hashedPassword = bcrypt.hashSync(req.body.password, 8);
    
         User.create({
         name : req.body.name,
        email : req.body.email,
        password : hashedPassword
            })
            .then(user=>{
               // create a token
        var token = jwt.sign({ id: user._id }, config.secret, {
          expiresIn: 86400 // expires in 24 hours
        });
        return res.status(200).json({ auth: true, token: token });
    
            }).catch(err=>{
    
    
              return res.status(500).send("There was a problem registering the user. "+err)
    
            }); 
    
    
    
    };
    

    This worked for me and the code now works as expected.