skad0
skad0

Reputation: 163

Express.js and Sequelize: does not define models

I am developing small app using express.js and sequelize. Now I have a problem. I go with this tutorial and stucked.

I am getting

TypeError: Cannot read property 'findAll' of undefined

for

router.get('/news', function (req, res, next) {
  models.Article.findAll().then(function(article) {
    res.json(article);
  });
});

My model:

'use strict';
module.exports = function(sequelize, DataTypes) {
  var Article = sequelize.define('Article', {
    title: DataTypes.STRING,
    content: DataTypes.TEXT
  }, {
    classMethods: {
      associate: function(models) {
        // associations can be defined here
      }
    }
  });
  return Article;
};

I host project by github, any code you can see there.

Thanks for your help.

UPD: Added console.log(models) to route /news.

Upvotes: 0

Views: 597

Answers (3)

skad0
skad0

Reputation: 163

After debugging, I found that default models/index.js has an error. When it iterate through files in models folder, there is an condition in filter

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

This will return false if file has an .js extension, that uncorrect. Fix it to

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

and it will work. Good luck!

Full correct construction:

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

Upvotes: 0

cfogelberg
cfogelberg

Reputation: 1488

The bug is in models/index.js. In there you have:

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

This excludes all files which end in .js. Changing the final condition to file.slice(-3) === '.js' means that article.js is not filtered out. Article is defined in article.js.

To debug this I added the following line to your router function for GET /news:

console.log('KEYS TO models: ' + JSON.stringify(Object.keys(models)));

This showed me that the only members of models were sequelize and Sequelize:

Upvotes: 1

syldor
syldor

Reputation: 1176

It may be related to naming conventions, because Sequelize adds plural to models name. Good practice is to use plural names in your models definition so you're not tricked by that later in your code.

Try changing Article to Articles in your code and your model declaration.

Upvotes: 0

Related Questions