Matis
Matis

Reputation: 631

NodeJS unable to import Sequelize.js model (ES6)

I'm running NodeJS with Express and Seqeulize and I have a file controllers/rooms.js importing Room from models/room.js.

import Room from '../models'

export function list(req, res) {
    return Room
        .findAll()
        .then((rooms) => res.status(200).send(rooms))
        .catch((error) => res.status(400).send(error))
}

Bellow is models/room.js (There is also index.js file generate by sequelize-cli in the same directory)

'use strict'

export default (sequelize, DataTypes) => {

    const Room = sequelize.define('Room', {
        name: DataTypes.STRING
    })

    return Room
}

And I have a route app.get('/rooms', list), but when I access this route I get this error:

TypeError: _models2.default.findAll is not a function
    at list (/Users/matis/Documents/apps/node-docker-test/app/database/controllers/rooms.js:21:10)
    at Layer.handle [as handle_request] (/Users/matis/Documents/apps/node-docker-test/node_modules/express/lib/router/layer.js:95:5)
    at next (/Users/matis/Documents/apps/node-docker-test/node_modules/express/lib/router/route.js:137:13)
    at Route.dispatch (/Users/matis/Documents/apps/node-docker-test/node_modules/express/lib/router/route.js:112:3)
    at Layer.handle [as handle_request] (/Users/matis/Documents/apps/node-docker-test/node_modules/express/lib/router/layer.js:95:5)
    at /Users/matis/Documents/apps/node-docker-test/node_modules/express/lib/router/index.js:281:22
    at Function.process_params (/Users/matis/Documents/apps/node-docker-test/node_modules/express/lib/router/index.js:335:12)
    at next (/Users/matis/Documents/apps/node-docker-test/node_modules/express/lib/router/index.js:275:10)
    at expressInit (/Users/matis/Documents/apps/node-docker-test/node_modules/express/lib/middleware/init.js:40:5)
    at Layer.handle [as handle_request] (/Users/matis/Documents/apps/node-docker-test/node_modules/express/lib/router/layer.js:95:5)
    at trim_prefix (/Users/matis/Documents/apps/node-docker-test/node_modules/express/lib/router/index.js:317:13)
    at /Users/matis/Documents/apps/node-docker-test/node_modules/express/lib/router/index.js:284:7
    at Function.process_params (/Users/matis/Documents/apps/node-docker-test/node_modules/express/lib/router/index.js:335:12)
    at next (/Users/matis/Documents/apps/node-docker-test/node_modules/express/lib/router/index.js:275:10)
    at query (/Users/matis/Documents/apps/node-docker-test/node_modules/express/lib/middleware/query.js:45:5)
    at Layer.handle [as handle_request] (/Users/matis/Documents/apps/node-docker-test/node_modules/express/lib/router/layer.js:95:5)
    at trim_prefix (/Users/matis/Documents/apps/node-docker-test/node_modules/express/lib/router/index.js:317:13)
    at /Users/matis/Documents/apps/node-docker-test/node_modules/express/lib/router/index.js:284:7
    at Function.process_params (/Users/matis/Documents/apps/node-docker-test/node_modules/express/lib/router/index.js:335:12)
    at next (/Users/matis/Documents/apps/node-docker-test/node_modules/express/lib/router/index.js:275:10)
    at Function.handle (/Users/matis/Documents/apps/node-docker-test/node_modules/express/lib/router/index.js:174:3)
    at Function.handle (/Users/matis/Documents/apps/node-docker-test/node_modules/express/lib/application.js:174:10)

I'm sure I have my imports/exports messed up but I don't know how.

models/index.js file bellow

'use strict'

import { readdirSync } from 'fs'
import { basename as _basename, join } from 'path'
import Sequelize from 'sequelize'
const basename = _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)
}

readdirSync(__dirname)
    .filter(file => {
        return (file.indexOf('.') !== 0) && (file !== basename) && (file.slice(-3) === '.js')
    })
    .forEach(file => {
        const model = sequelize['import'](join(__dirname, file))
        db[model.name] = model
    })

Object.keys(db).forEach(modelName => {
    if (db[modelName].associate) {
        db[modelName].associate(db)
    }
})

db.sequelize = sequelize
db.Sequelize = Sequelize

export default db

It works when I call it like this: return Room.Room.findAll()... Therefore i can rename the import to this: import models from '../models' and call it this way: return models.Room.findAll()...

However why can't I just call it return Room.findAll()..., how should the import be formulated ??

Upvotes: 4

Views: 12362

Answers (3)

Modem Rakesh goud
Modem Rakesh goud

Reputation: 1788

I was trying to setup the existing code and faced the above issue. The issue got resolved by downgrading my node version to 10.18.0 from the latest version.

It seems to be that the code was originally developed using node version 10.

Upvotes: 0

Fateh Farooqui
Fateh Farooqui

Reputation: 144

Assuming you have babel setup for using ES6 imports you can try this approach to export a Sequelize model in ES6.

// db config file

import Sequelize from 'sequelize';

export const sequelize = new Sequelize(
  config.database.name,
  config.database.user,
  config.database.password,
  {
    host: config.database.host,
    dialect: config.database.dialect,
    pool: config.database.pool,
    operatorsAliases: false
  }
);

// Model

import Sequelize from 'sequelize';
import { sequelize } from '../database/db';

const User = sequelize.define(
  'table_name',
  {
    id: {
      type: Sequelize.INTEGER,
      primaryKey: true,
      autoIncrement: true
    },
    name: {
      type: Sequelize.STRING,
      allowNull: false
    },
    email: {
      type: Sequelize.STRING,
      allowNull: false
    },
    password: {
      type: Sequelize.STRING,
      allowNull: false
    }
  },
  { freezeTableName: true }
);

export default User;

Upvotes: 9

tmw
tmw

Reputation: 1474

Last time when I worked with Sequelize it was not working well with ES6 features. My guess is that models/room.js is not exporting model properly due to export default. You can try changing that line to old style module.exports;

export default (sequelize, DataTypes) => {
.....
To
.....
module.exports = (sequelize, DataTypes) => {

and see if that solves the import problem.

When importing in controller you can do this;

const Room = require('../models').Room;

this is old way to do imports and now your code should work. :)

If you want to try with ES6 you can do something like;

import {Room} from '../models'

I'm not sure if this ES6 import works here!

Upvotes: 1

Related Questions