1

I get an issue using SequelizeJS and NodeJS.

My error message when I execute the npm bin/www command :

EventEmitter#success|ok is deprecated, please use promise-style instead.

Executing (default): CREATE TABLE IF NOT EXISTS `ArticleCategories` (`id` INTEGER NOT NULL auto_increment , `name` VARCHAR(255), `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB;
Executing (default): SHOW INDEX FROM `ArticleCategories`

I don't understand why the CREATE TABLE is executed because my table is already on place...

My model :

module.exports = function (db, Types) {
  var ArticleCategory = db.define('ArticleCategory', {
    name: {
      type: Types.STRING
    },
  }, {
    classMethods:{
      associate: function (models) {
        ArticleCategory.hasMany(models.Article);
      }
    }
  });
  return ArticleCategory;
};

And the dao, of the current model :

var dbContext = require('./../../db/DbContext');
var _ = require('lodash');

var ArticleCategoryDao = function () {
  this.context = dbContext.entities;
};

_.extend(ArticleCategoryDao.prototype, {

  getAll: function (callback) {
    return this.context.ArticleCategory.findAll({include: [{ model: this.context.Article}]});
  },

  get: function (id, callback) {
    return this.context.ArticleCategory.find(id);
  },

  save: function(properties, callback){
    this.context.ArticleCategory.create(properties)
    .success(function (category) {
      callback(null, category);
    })
    .error(function (error) {
      callback(error, null);
    });
  },

  update: function (properties, callback) {
    this.get(properties.id).success(function (category) {
      if(category){
        category.updateAttributes(properties).success(function (category) {
          callback(null, category);
        }).error(function (error) {
          callback(error, category);
        });
      }else{
        callback('Aucune catégorie avec l\'id :' + properties.id, null);
      }
    });
  },

  delete: function (id, callback) {
    this.context.ArticleCategory.find(id).success(function (category) {
      if(category){
        category.destroy().success(callback);
      }
      else{
        callback('Aucune catégorie avec l\'id :' + id);
      }
    })
    .error(callback);
  }
});

module.exports = ArticleCategoryDao;
tonymx227
  • 5,293
  • 16
  • 48
  • 91
  • 1
    Check if you're calling `sync()` somewhere in your code. – cgf Mar 26 '15 at 15:11
  • Yes I'm calling sync() in my `DbContext`... – tonymx227 Mar 26 '15 at 15:28
  • That's your problem then. :) When you're calling `sync()`, Sequelize will try to sync (surprise!) your database with what definitions you have in your Sequelize models. I don't know exactly all the ramifications of sync(), but delete it and you will probably notice that the CREATE TABLE statements are not there anymore. – cgf Mar 26 '15 at 16:01
  • Ok I delete the `sync()` function but if I drop all tables, my script will create back all tables? – tonymx227 Mar 26 '15 at 16:04
  • Nope. If you delete `sync()`, then Sequelize will not try to create your tables again. – cgf Mar 26 '15 at 22:52

1 Answers1

0

Hmm there are several issues in your questions. Also in some of the way you are using sequelize, was not the way the designers have intended for.

1) CREATE TABLE.

As mentioned by @cgc, #sync() is an initialization call. Think of it as big bang. You only every call it once at the beginning and then you take it away.

2) EventEmitter#success|ok is deprecated, please use promise-style instead.

Please refer to my stackoverflow answer here: Sequelize associations - please use promise-style instead

You shouldn't use #success() and #error() handlers anymore. However, BC is maintained on them. Then again, I'm not entirely sure how well the tests will cover on them moving forward and you just might run into bugs.

3) You can simplify your code by returning Promises.

The flow that you are writing, might setting you up for trouble. You have so many different ways of handling your error.

Subscribe to a simple promise flow instead. All sequelize instances and their methods will return promises. These promises can be returned to the parent promise chain so that you can have just 1 "success" and "error" handlers. And you can always like use throw to pass the error into your 1 and only error handling function.

Example of your #delete() method re-written:

  delete: function (id, callback) {
    // returns this parent promise to its caller
    return this.context.ArticleCategory.find(id).then(function (category) {
        if (!category) throw 'Aucune catégorie avec l\'id :' + id;

        // returns category promise back to its parent promise
          return category.destroy().then(callback);
    })
    // all errors within this parent promise scope will bubble up this this one catch handler.
    .catch(callback);
  }

Additional.

Subsequently, your #update() method can also be re-written as such:

update: function (properties, callback) {
    return this.context.find(properties.id).then(function(category) {
        if(!category) throw 'Aucune catégorie avec l\'id :' + properties.id';

        //don't need the id attribute. optional, but i feel deleting it is better.
        delete properties.id     
        return category
            .updateAttributes(properties)
            .then(function(category) {
                callback(null, category);
        });

    }).catch(callback);
}
Community
  • 1
  • 1
Calvintwr
  • 8,308
  • 5
  • 28
  • 42