how to fix getting undefined for model classes using sequelize? - javascript

I am learning to use sequelize with my Next.js app.I set up the sequelize, used the cli to generate migrations, created the model (user) , and when i try to test it, going to the http://localhost:3000/api/app . i get an error -> Cannot read property 'findAll' of undefined.
my model class is coming up as undefined. anyone has any idea?
*director structure
MyApp
...
> database
- db.js
> migrations
> models
-user.js
> node_modules
> pages
> api
- app.js
db.js
const Sequelize = require('sequelize');
const db = new Sequelize('mydb', 'root', 'pass', {
host: "localhost",
port: 3306,
dialect: 'mysql',
operatorsAliases:false,
logging: function () {},
pool: {
max: 5,
min: 0,
idle: 10000
},
dialectOptions: {
socketPath: "/var/run/mysqld/mysqld.sock"
},
define: {
paranoid: true
}
});
db.authenticate().then(() => {
console.log('connection error');
}).catch(err => {
console.log('Connection successful');
});
module.exports = db;
model/User.js
module.exports = (sequelize, DataTypes) => {
const user = sequelize.define("User", {
id : {
type: DataTypes.INTEGER(11),
allowNull: false,
autoIncrement:true,
primaryKey:true
},
firstName : {
type: DataTypes.STRING(50),
allowNull: false
}
lastName : {
type: DataTypes.STRING(50),
allowNull: false
},
created: {
type: 'TIMESTAMP',
defaultValue: DataTypes.literal('CURRENT_TIMESTAMP'),
allowNull: false
},
updated:{
type: 'TIMESTAMP',
defaultValue: DataTypes.literal('CURRENT_TIMESTAMP'),
allowNull: false
}
});
return user;
};
pages/api/app.js
const models = require('../../models')
export default (req, res) => {
models.user.findAll(); //error => Cannot read property 'findAll' of undefined
};

You define uppercase User in the User.js file, so you have to use it uppercase:
const models = require('../../models');
export default async (req, res) => {
const users = await models.User.findAll();
console.log(users);
};

Related

mongoDB collection creation

i have a problem with adding a collection into my database in mongodb atlas.
I have managed to import this collection before but i accidentally deleted it and now i can't upload it again. there is no error in my terminal. There for i don't know what is wrong with my code.. (image of my code and terminal are attached below)
There is anyone who might know why is this can happen?
EDIT
I tried to open a new database and my all the collections was imported to it and once again, only the product collection doesn't
//////////////////////////////////
/* require('dotenv').config({ path: '/.env' }) */
const path = require('path')
require('dotenv').config({ path: path.resolve(__dirname, '..', '.env') })
console.dir(process.env.MONGO_URI)
const mongoose = require('mongoose')
const connectDB = async () => {
try {
mongoose.connect(process.env.MONGO_URI, {
useCreateIndex: true,
useNewUrlParser: true,
useUnifiedTopology: true,
})
console.log('MongoDB connection SUCCESS')
} catch (error) {
console.error('MongoDB connection FAIL')
process.exit(1)
}
}
console.dir(process.env.MONGO_URI)
module.exports = connectDB
////////////////////////////////////////////////////////////////
require('dotenv').config()
const productsData = require('./data/products')
const connectDB = require('./config/db')
const Product = require('./models/product')
connectDB()
const importData = async () => {
try {
/* Product.deleteMany({}) */
Product.insertMany(productsData)
console.dir('Data Imported Successfuly')
process.exit()
} catch (error) {
console.log(error)
console.error('Error Ocured In Imported Data Process', error)
process.exit(1)
}
}
importData()
my model schema
const mongoose = require('mongoose')
const products = require('../data/products')
const productSchema = new mongoose.Schema({
name: {
type: String,
required: true,
},
description: {
type: String,
required: true,
},
price: {
type: Number,
required: true,
},
countInStock: {
type: Number,
required: true,
},
imageUrl: {
type: String,
required: true,
},
})
module.exports = mongoose.model('Products', productSchema)
my code and terminal image
Product.insertMany(productsData) returns a promise, but you aren't waiting for that promise to finish before exiting the process. Add an await before it and you should be okay.
Try this to create your schema instead
const { Schema } = mongoose;
const productSchema = new Schema({
name: {
type: String,
required: true,
},
description: {
type: String,
required: true,
},
price: {
type: Number,
required: true,
},
countInStock: {
type: Number,
required: true,
},
imageUrl: {
type: String,
required: true,
},
})
const Product = mongoose.model("Product", productSchema);
Product.createCollection();

Sequelize foreing key is not creating

I try to create a relation between 2 tables with Sequelize in NodeJS for MariaDB.
I have 2 tables order and local, the table order needs one of the information of the table local.
The order table contains information about an order (id: 1, type: Jacket, color: blue, tracking_number: TR123)
The table local contains information about the place where the order is stored (address: 20 rue madeline, city: Paris)
I tried to link the two tables but it does not work, the foreing key is not created
models/order.js
module.exports = (sequelize, DataTypes) => {
const Order = sequelize.define('order', {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true
},
trackingNumber: {
type: DataTypes.STRING,
allowNull: false
},
type: {
type: DataTypes.STRING(50),
allowNull: false
},
color: {
type: DataTypes.STRING(50),
allowNull: false
},
email: {
type: DataTypes.STRING,
allowNull: false
},
tel: {
type: DataTypes.STRING(10),
allowNull: false
}
}, {
timestamps: true,
createdAt: true,
updatedAt: 'updateTimestamp'
})
Order.associate = function (models) {
Order.hasOne(models.local);
}
return Order;
}
models/local.js
module.exports = (sequelize, DataTypes) => {
const Local = sequelize.define('local', {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true
},
adress: {
type: DataTypes.STRING,
allowNull: false
},
informations_about: {
type: DataTypes.STRING,
allowNull: false
},
contact: {
type: DataTypes.STRING,
allowNull: false
},
city: {
type: DataTypes.STRING,
allowNull: false
},
zip: {
type: DataTypes.STRING(5),
allowNull: false
},
}, {
timestamps: true,
createdAt: true,
updatedAt: 'updateTimestamp'
})
return Local;
}
app.js
// Imports
const express = require('express')
const morgan = require('morgan')
const db = require('./database')
const sequelize = require('./database').sequelize;
var apiRouter = require('./apiRouter.js').router;
var helmet = require('helmet');
const app = express()
const port = process.env.PORT || 3000;
// Init server
app.use(morgan('combined'))
// Parser config
app.use(express.urlencoded({ extended: false }));
app.use(express.json());
// Security API
app.use(helmet());
app.disable('x-powered-by');
app.use(({ res }) => {
res.status(404).json({ message: "404 Not Found" })
})
db.sequelize.authenticate()
.then(_ => console.log("La connexion à bien été établie."))
.catch(error => console.log(`error ${error}`))
db.sequelize.sync({ force: true })
.then(_ => {
console.log("Base de donnée synchronisée.")
app.use('/api/', apiRouter);
})
app.listen(port, () => {
console.log("Server is up and listening in " + port)
})
database.js
const fs = require('fs')
const path = require('path')
const { Sequelize } = require('sequelize')
const db = {}
const models = path.join(__dirname, 'models') // correct it to path where your model files are
const sequelize = new Sequelize(
'',
'',
'',
{
host: 'localhost',
dialect: 'mariadb',
dialectOptions: {
useUTC: false, // for reading from database
},
pool: {
max: 5,
min: 0,
acquire: 30000,
idle: 10000
},
logging: false
}
)
var basename = path.basename(module.filename)
fs
.readdirSync(models)
.filter(function (file) {
return (file.indexOf('.') !== 0) && (file !== basename) && (file.slice(-3) === '.js')
})
.forEach(function (file) {
const model = require(path.join(__dirname + '/models', file))(sequelize, Sequelize.DataTypes)
db[model.name] = model
})
Object.keys(db).forEach(function (modelName) {
if (db[modelName].associate) {
db[modelName].associate(db)
}
})
db.Sequelize = Sequelize // for accessing static props and functions like Op.or
db.sequelize = sequelize // for accessing connection props and functions like 'query' or 'transaction'
module.exports = db
Despite the associate function in the model/order.js it does not work, I have no key in my order table
You have to manually call all associate functions in order to register associations between models and only after all models are already registered in the Sequelize instance. You can look at my other answer to see how you can do it.
And please show the content of database module and then I probably correct my answer or append more useful tips.

TypeError: Cannot read property 'findAll' of undefined (mariaDB, ExpressJs)

TypeError: Cannot read property 'findAll' of undefined
findAll function makes error, but Connection was successful.
And database is also created under the name managers.
app.js
models
index.js
maria
manager.model.js
bin
www.js
models/index.js
const { Sequelize } = require('sequelize');
const manager = new Sequelize({
dialect: 'mariadb',
host: '127.0.0.1',
port: '13306',
username: 'xxx',
password: 'xxx',
database: 'test',
timezone: 'Asia/Seoul'
});
require('./maria/manager.model')(manager);
module.exports=manager;
models/maria/manager.model.js
const { DataTypes } = require('sequelize');
module.exports = (sequelize) => {
sequelize.define('manager', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: DataTypes.INTEGER
},
name: {
allowNull: false,
type: DataTypes.STRING,
}
}, {timestamps: true }).sync({force:false});
};
app.js
const express = require('express');
const app = express();
const db = require('./models');
console.log(`Checking database connection...`);
// It works!
db.authenticate().then(()=>{
console.log('Database connection OK!');
});
// It makes error!
const find_test = db.manager.findAll();
console.log(find_test);
First of all what is containing your manager variable ?
your manager variable is containing the connection sequelize. Your objectif is to request your table manager but you can't to this with the variable. Because he doesn't contain table specification but database connection.
const { DataTypes } = require('sequelize');
module.exports = (sequelize) => {
return sequelize.define('manager', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: DataTypes.INTEGER
},
name: {
allowNull: false,
type: DataTypes.STRING,
}
}, {timestamps: true });
};
In this file, you need to return the definition of your table.
const { Sequelize } = require('sequelize');
const manager = new Sequelize({
dialect: 'mariadb',
host: '127.0.0.1',
port: '13306',
username: 'xxx',
password: 'xxx',
database: 'test',
timezone: 'Asia/Seoul'
});
const myTable = require('./maria/manager.model')(manager);
module.exports= {
manager, myTable
};
and in this file, you need to store the return value in a variable.and export it.
const express = require('express');
const app = express();
const { manager, myTable }= require('./models');
console.log(`Checking database connection...`);
// It works!
manager.authenticate().then(()=>{
console.log('Database connection OK!');
});
const find_test = myTable.findAll();
console.log(find_test);
Finaly in the next file, import the new exported variables ! and Enjoy !
app.js
sequelize
models
manager.model.js
index.js
app.js
const maria = require('./sequelize');
const { models } = require('./sequelize');
console.log(`Checking database connection...`);
maria.authenticate()
.then(()=>{
console.log('Database connection OK!');
});
const test = models.manager.findOne()
sequelize/index.js
const { Sequelize } = require('sequelize');
const maria = new Sequelize({
dialect: 'mariadb',
host: '127.0.0.1',
port: '13306',
username: 'xxxx',
password: 'xxxx',
database: 'test',
timezone: 'Asia/Seoul'
});
require('./models/manager.model')(maria)
module.exports=maria;

Sequelize middleware code not recognized by node app

I am new to sequelize and I created a middleware called "db.js" with a connection to a mysql table called "users". Everytime, I attempt to run the app.js, I am getting this error: "TypeError: app.use() requires a middleware function".
However, I have a middleware function. See the code below: Am I missing something? I have the module.exports object at the end.
Should I have initialize sequelize?
db.js file
const Sequelize = require("sequelize");
const mysql = require("mysql");
const mysql2 = require("mysql2");
const db = {}
const sequelize = new Sequelize("smalldata", "root", "xxxx", {
host: "localhost",
dialect: "mysql",
operatorsAliases: false,
pool: {
max: 5,
min: 0,
acquire: 30000,
idle: 90000
}
})
sequelize
.authenticate()
.then(() => {
console.log('Connection has been established successfully.');
})
.catch(err => {
console.error('Unable to connect to the database:', err);
});
db.sequelize = sequelize
db.Sequelize = Sequelize
module.exports = db;
app.js file
const sequelize = require("sequelize");
const db = require("./middleware/db");
const express = require("express");
//Initialize Middleware
app.use(cors());
app.use(expressLayouts);
app.use(logger);
app.use(db);
user.js file
const Sequelize = require("sequelize");
const db = require("./db");
const User = db.sequelize.define(
'users',
{
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
},
first_name: {
type: Sequelize.STRING
},
last_name: {
type: Sequelize.STRING
},
email: {
type: Sequelize.STRING
},
password: {
type: Sequelize.STRING
}
},
{
timestamps: true
},
)
// Note: using `force: true` will drop the table if it already exists
User.sync({ force: true }).then(() => {
// Now the `users` table in the database corresponds to the model
definition
return User.create({
first_name: 'John',
last_name: 'Hancock',
email:'johnhancock#gmail.com',
password:'johnny'
});
});
module.exports = User
I found the error:
Capitalize error in app.js file:
const Sequelize = require("sequelize");
instead of:
const sequelize = require("sequelize");

Sequelize connection with Nodejs

I am facing issue on connection of SEQUELIZE(mysql) with NodeJs. Though connection is established but models are not properly configured. I have use this approach --
./config/sequelize-conn.js
'use strict';
var sequelize = function (config, Sequelize) {
var sql = new Sequelize(config.mysql.db, config.mysql.user, config.mysql.pass, {
host: config.mysql.host,
dialect: 'mysql', //|'sqlite'|'postgres'|'mssql'
pool: {
max: 5,
min: 0,
idle: 10000
},
//logging: true,
underscored: true
});
sql
.sync({force: true})
//.authenticate()
.then(function () {
console.log('Connection has been established successfully with mysql.');
}, function (error) {
console.log('Connection with mysql failed.', error);
});
return sql;
};
module.exports = sequelize;
//server.js
var sequelize = require('sequelize');
var sqlConnection = require('./config/sequelize-conn')(config, sequelize);
I wish to directly use model this way ..
models/HotelGroup.js
var Sequelize = require('sequelize');
var sequelize = require('../../config/sequelize-conn');
var HotelGroup = Sequelize.define('hotel_chains', {
id: {
type: Sequelize.INTEGER(11),
allowNull: false,
primaryKey: true,
autoIncrement: true
},
hotel_name: {
type: Sequelize.STRING,
allowNull: false
},
hotel_code: {
type: Sequelize.STRING,
allowNull: false
},
status: {
type: Sequelize.BOOLEAN,
allowNull: false,
defaultValue: '1'
}
}, {
tableName: 'hotel_chains',
timestamps: false,
paranoid: true // Model tableName will be the same as the model name
});
module.exports = HotelGroup;
Its giving me error that sequelize.define is not a function.
Though connection is establishing but when I try to access any model in service file using require. It breaks with this error message. Where I am doing wrong.
I think you need to use the instance of sequelize, not the class. So sequelize.define not Sequelize.define.
Also, you need to instantiate it properly: var sequelize = new Sequelize(...)

Categories