Home > Software engineering >  Why do I get `Cannot read properties of undefined` while trying to import a Sequelize model?
Why do I get `Cannot read properties of undefined` while trying to import a Sequelize model?

Time:12-06

This is based on my previous question but more simple because I've figured out the issue is because I did something wrong with module.exports. I'm trying to figure out why I get a TypeError whenever I use any function of the model I created in another file. I have this test code:
index.js:

const { Test } = require('./model.js');

(async () => {
  const test = await Test.create({ name: 'test', desc: 'hello world' });

  console.log(test.name);
})();

db-init.js (run manually):

const { Sequelize, DataTypes } = require('sequelize');

const db = new Sequelize({
  dialect: 'sqlite',
  storage: './database.sqlite',
});

require('./model.js')(db, DataTypes);

db.sync({ force: true }).then(async () => {
  console.log('db connected');
}).catch(console.error);

model.js:

module.exports = (db, DataTypes) => {
  return db.define('test', {
    name: DataTypes.STRING,
    desc: DataTypes.TEXT,
  });
}

The code should print "hello world", but instead I get TypeError: Cannot read properties of undefined (reading 'create'). Sorry if this question is poorly worded.

CodePudding user response:

It looks like you're exporting a function that defines a model rather than the model itself from model.js. Because of this, when you try to use Test.create() in index.js, Test is undefined.

To fix this, you can either export the model itself from model.js and import it directly in index.js, or you can call the function that you're currently exporting and assign the result to a variable before using it.

Here's an example of how you could export the model itself from model.js:

const { Sequelize, DataTypes } = require('sequelize');

const db = new Sequelize({
  dialect: 'sqlite',
  storage: './database.sqlite',
});

const Test = db.define('test', {
  name: DataTypes.STRING,
  desc: DataTypes.TEXT,
});

module.exports = { Test };

You can then import the model directly in index.js like this:

const { Test } = require('./model.js');

(async () => {
  const test = await Test.create({ name: 'test', desc: 'hello world' });

  console.log(test.name);
})();

Alternatively, you could keep the current implementation of model.js and call the exported function to get the model, like this:

const { Sequelize, DataTypes } = require('sequelize');

const db = new Sequelize({
  dialect: 'sqlite',
  storage: './database.sqlite',
});

const defineTestModel = require('./model.js');
const Test = defineTestModel(db, DataTypes);

(async () => {
  const test = await Test.create({ name: 'test', desc: 'hello world' });

  console.log(test.name);
})();

Update To import the db object in your index.js file, you can export it in your db-init.js file and then import it in your index.js file.

Here is an example of how you can do this:

db-init.js:

const { Sequelize, DataTypes } = require('sequelize');

// Define the db object and export it
const db = new Sequelize({
  dialect: 'sqlite',
  storage: './database.sqlite',
});

module.exports = db;

test.js:

// Import the db object and the Test model
const db = require('./db-init.js');
const { Test } = require('./model.js');

(async () => {
  const test = await Test.create({ name: 'test', desc: 'hello world' });

  console.log(test.name);
})();
  • Related