Sequelize findAll is not a function

Issue

I’m making a project with Sequelize and I’m stucked in this step. The problem is that when I try to log in and the passport-local code is executed, when it reaches the User.findAll(…) it throws that findAll is not a function.

If I make console.log(User) it shows [function].

My structure:

  • /config/config.js
  • /config/passport.js
  • /models/index.js
  • /models/nuke_users.js (generated by sequelize-auto)
  • /index.js

config.js:

//Setting up the config
var Sequelize = require('sequelize');
var sequelize = new Sequelize('rocarenav2', 'root', '123456', {
   host: "localhost",
   port: 3306,
   dialect: 'mysql'
});

module.exports = sequelize;

passport.js:

// config/passport.js

// load all the things we need
var LocalStrategy   = require('passport-local').Strategy;

// load up the user model
var User            = require('../models/nuke_users');

var crypto          = require('crypto');

function hashPasswordForNuke(password) {
    return md5password =        crypto.createHash('md5').update(password).digest('hex');
}

// expose this function to our app using module.exports
module.exports = function(passport) {

// =========================================================================
// passport session setup ==================================================
// =========================================================================
// required for persistent login sessions
// passport needs ability to serialize and unserialize users out of session

// used to serialize the user for the session
passport.serializeUser(function(user, done) {
    done(null, user.id);
});

// used to deserialize the user
passport.deserializeUser(function(id, done) {
    User.findById(id, {})
    .then(function (user) {
        done(err, user);
    })
    .catch(function (error){
        done(error);
    });
});



// =========================================================================
// LOCAL LOGIN =============================================================
// =========================================================================
// we are using named strategies since we have one for login and one for signup
// by default, if there was no name, it would just be called 'local'

passport.use('local-login', new LocalStrategy({
    // by default, local strategy uses username and password, we will override with email
    usernameField : 'email',
    passwordField : 'password',
    passReqToCallback : true // allows us to pass back the entire request to the callback
},
function(req, email, password, done) { // callback with email and password from our form
    User.findAll({
        where: {
            'user_email': email
        }
    }).then(function (user) {
        if(!user)
            return done(null, false, req.flash('loginMessage', 'No user found.')); // req.flash is the way to set flashdata using connect-flash

        // if the user is found but the password is wrong
        if ((user.user_password).localeCompare(hashPasswordForNuke(password)) === -1)
            return done(null, false, req.flash('loginMessage', 'Oops! Wrong password.')); // create the loginMessage and save it to session as flashdata

        return done(null, user);
    })
    .catch(function (error){
        done(error);
    });

}));

};

models/index.js

'use strict';

var fs        = require('fs');
var path      = require('path');
var Sequelize = require('sequelize');
var basename  = path.basename(module.filename);
var config    = require(__dirname + '/../config/config');
var db        = {};

//Create a Sequelize connection to the database using the URL in         config/config.js
var sequelize = config;

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

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

//Export the db Object
db.sequelize = sequelize;
db.Sequelize = Sequelize;

module.exports = db;

/models/nuke_users.js

/* jshint indent: 2 */

module.exports = function(sequelize, DataTypes) {
return sequelize.define('nuke_users', {
   user_id: {
      type: DataTypes.INTEGER(11),
      allowNull: false,
      primaryKey: true,
      autoIncrement: true
   },
   username: {
      type: DataTypes.STRING,
      allowNull: false,
      defaultValue: "",
      references: {
         model: 'reps_table',
         key: 'PostName'
      }
   },
   user_email: {
      type: DataTypes.STRING,
      allowNull: false,
      defaultValue: ""
   },
   user_avatar: {
      type: DataTypes.STRING,
      allowNull: false,
      defaultValue: ""
   },
   user_password: {
      type: DataTypes.STRING,
      allowNull: false,
      defaultValue: ""
   }
 }, {
    tableName: 'nuke_users'
 });
};

/index.js

...
var models = require('./models/');
...

So, what am I doing wrong?

Solution

The nuke_users module is exporting a function that, when called, returns the Model. Because you aren’t calling this function, it is not returning the Model, and thus the function you are looking for does not exist.

To call this exported function you would need to pass in the sequelize instance and DataTypes, as so:

var User = require('../models/nuke_users')(sequelize, DataTypes);

In your case you are using a loader in the index.js file, and it is exporting the db object which contains the models keyed by their name.

var models = require('../models'); // loads index.js
var User = models.nuke_user;       // the model keyed by its name
User.findOne(...);                 // search the model

Answered By – doublesharp

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published