Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cant retrieve the model name for Sequelize with mysql

I am new to nodejs and the Sequelize ORM framework. I am trying to get it to work with mysql. I have made some great progress but at the moment I am stuck at the part where sequelize needs to load in the models. But I am getting an error where the name is retrieved from the file.

www

var debug = require('debug')('sampleapp')
var app = require('../server');
var models = require('../model');

app.set('port', process.env.PORT || 3000);

//server running
models.sequelize.sync().then(function () {
  var server = app.listen(app.get('port'), function(){
    debug('The magic is happening on port '+server.address().port);
  });
});

index.js

"use strict"
var fs        = require('fs');
var path      = require('path');
var Sequelize = require('sequelize');
var debug = require('debug');
var env = process.env.NODE_ENV || "development";
var config    = require(path.join(__dirname, '..', 'config', 'config.json'))[env];
var sequelize = new Sequelize(config.database, config.username, config.password, config);
var db        = {};

fs.readdirSync(__dirname)
  .filter(function(file) {
    return (file.indexOf(".") !== 0) && (file !== 'index.js')
  })
  .forEach(function(file) {
    var model = sequelize['import'](path.join(__dirname, file))
    db[model.name] = model
  });


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

module.exports = db;

user.js

module.exports = function(sequelize, DataType){

  var User = sequelize.define('user', {
    name: DataType.STRING,
    password: DataType.STRING,
    lastName: DataType.STRING,
    email: DataType.STRING,
    gender: DataType.CHAR,
    cellNumber: DataType.INTEGER
  }, {
    instanceMethods : {
      create : function(onSuccess, onError){
        var name = this.name;
        var lastName = this.lastName;
        var email = this.email;
        var gender = this.gender;
        var cellNumber = this.cellNumber;
        var password = this.password;

        var shasum = crypto.createHash('sha1');
        shasum.update(password);
        password = shasum.digest('hex');

        User.build({name: name, lastName: lastName, email: email, gender: gender, cellNumber: cellNumber, password: password})
          .save().success(onSuccess).error(onError);
      }
    }
  });
};

I keep getting this error at db[model.name] = model :

TypeError: Cannot read property 'name' of undefined

Have been on this error for a while now. any help would be greatly appreciated

like image 596
Andre Coetzee Avatar asked Feb 03 '16 16:02

Andre Coetzee


Video Answer


1 Answers

There's a chance that you're picking up a non-model file in the model directory. What other files do you have in that directory? You only want to import javascript files and your file filter isn't specific enough. Try forcing it to only detect javascript files. A simple way of doing this is checking the last three characters of the file name and making sure they're .js.

(file.slice(-3) === '.js')

Add it to the file filter like so:

.filter(function(file) {
    return (file.indexOf('.') !== 0) && (file !== "index.js") && (file.slice(-3) === '.js');
})

Another reason it could be failing is that the instance of sequelize isn't instantiating successfully and silently failing before you can actually import the models. I use something like this to ensure I have connectivity before the import:

var sequelize = new Sequelize(foo, bar, baz);
sequelize.authenticate().then(function() {
  console.log('Database connected and authenticated!');
  return true;
}).catch(function(err) {
  console.error('Failed to connect and authenticate', err);
  return false;
});

If you were to use something like this it would make it easier to spot errors. Try putting the database check above your existing code (or even just temporarily comment your code out) and confirm that you are actually successfully connecting. Once you can confirm you're connected it gets much easier to debug weird stuff.

Note: Don't leave the DB check in there once you confirm it's working. It's a Promise and doesn't play well with synchronous functions like fs.readdirSync().

like image 122
Pierce Avatar answered Sep 26 '22 14:09

Pierce