TheAmberlamps
TheAmberlamps

Reputation: 58

"TypeError: Cannot read property 'create' of undefined"

I'm building a simple site that handles users using Passport.js. I can run my server but when a user submits their signup information it spits out "TypeError: Cannot read property 'create' of undefined".

I know what's happening, I just can't understand why. The error gets thrown in api-routes.js, specifically in the api/signup function when it attempts to create a user via db.User.create. When I console.log(db), the first thing in the db object is

undefined: 'C:\\Users\\LENOVO\\Desktop\\code\\Breel\\models\\user.js'

...so the user model is being exported, it's just not defined?

Any and all help you can lend me is greatly appreciated!

user.js, from my models directory:

var bcrypt = require("bcryptjs");

module.exports = function (sequelize, DataTypes) {
  var User = sequelize.define("User", {
    email: {
      type: DataTypes.STRING,
      allowNull: false,
      unique: true,
      validate: {
        isEmail: true,
      },
    },
    password: {
      type: DataTypes.STRING,
      allowNull: false,
    },
  });
  User.prototype.validPassword = function (password) {
    return bcrypt.compareSync(password, this.password);
  };
  User.hook("beforeCreate", function (user) {
    user.password = bcrypt.hashSync(
      user.password,
      bcrypt.genSaltSync(10),
      null
    );
  });
  return User;
  };

index.js, from models (this and user.js are the only two files in my models directory)

"use strict";

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

let sequelize;
if (config.use_env_variable) {
  sequelize = new Sequelize(process.env[config.use_env_variable], config);
} else {
  sequelize = new Sequelize(
    config.database,
    config.username,
    config.password,
    config
  );
}

fs.readdirSync(__dirname)
  .filter((file) => {
    return (
      file.indexOf(".") !== 0 && file !== basename && file.slice(-3) === ".js"
    );
  })
  .forEach((file) => {
    const model = path.join(__dirname, file);
    sequelize["import"];
    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;

api-routes.js, from my routes directory:

var db = require("../models");
var passport = require("../config/passport");

module.exports = function (app) {
  app.post("/api/login", passport.authenticate("local"), function (req, res) {
    res.json("/members");
  });
  app.post("/api/signup", function (req, res) {
    console.log(req.body);
    console.log(db);
    db.User.create({
      email: req.body.email,
      password: req.body.password,
    })
      .then(function () {
        res.redirect(307, "/api/login");
      })
      .catch(function (err) {
        console.log(err);
        res.json(err);
      });
  });
  app.get("/logout", function (req, res) {
    req.logout();
    res.redirect("/");
  });
  app.get("/api/user_data", function (req, res) {
    if (!req.user) {
      res.json({});
    } else {
      res.json({
        email: req.user.email,
        id: req.user.id,
      });
    }
  });
};

Upvotes: 0

Views: 11177

Answers (1)

Anatoly
Anatoly

Reputation: 22813

You should correct a registration process of models:

.forEach((file) => {
    const modelFile = path.join(__dirname, file);
    const model = sequelize['import'](modelFile)
    db[model.name] = model;
  })

Upvotes: 2

Related Questions