Hello can somebody help me with this ? I was doing my controllers and I can access to my model like this "const { User } = require("../models/User");" but than when I send my request I had this message "TypeError: Cannot read property 'create' of undefined" so something was missing.
So I change my call model to this "const { User } = require("../models");".
And I went on my model index.js (so connection sequelize) and I add fs function and Objectif.key. After all those changes I have the error "No Sequelize instance passed".
So maybe somebody can help with this because I don't see the problem
So this is my model index.js
//sequelize importe
const fs = require("fs");
const path = require("path");
const Sequelize = require("sequelize");
const db = {};
const basename = path.basename(__filename);
let sequelize = new Sequelize("groupomania", "root", "root", {
host: "localhost",
dialect: "mysql",
});
sequelize
.authenticate()
.then(() => {
console.log("Connection has been established successfully!");
})
.catch((err) => {
console.log("Can't establish database connection:\n" + err);
});
fs.readdirSync(__dirname)
.filter((file) => {
console.log( file.indexOf(".") !== 0 && file !== basename && file.slice(-3) === ".js");
return (
file.indexOf(".") !== 0 && file !== basename && file.slice(-3) === ".js"
);
})
.forEach(file => {
const model = require(path.join(__dirname, file))(sequelize, Sequelize.DataTypes);
db[model.name] = model;
});
Object.keys(db).forEach((modelName) => {
if (db[modelName].associate) {
db[modelName].associate(db);
}
});
db.sequelize = sequelize;
db.Sequelize = Sequelize;
module.exports = db;
This is my model User.js
const { Model } = require("sequelize");
module.exports = (Sequelize, DataTypes) => {
class User extends Model {
toJSON() {
return {
...this.get(),
password: undefined,
};
}
}
User.init(
{
id: { type: DataTypes.UUID, defaultValue: DataTypes.UUIDV4 },
nom: { type: DataTypes.STRING, allowNull: false },
prenom: { type: DataTypes.STRING, allowNull: false },
email: {
type: DataTypes.STRING,
allowNull: false,
validate: { notNull: true, notEmpty: true, isEmail: true },
},
status: { type: DataTypes.STRING, allowNull: false },
password: { type: DataTypes.STRING, required: true },
},
{ Sequelize, tableName: "users", modelName: "User" }
);
return User;
};
My controllers/user.js
/*const bcrypt = require("bcrypt");
const jwt = require("jsonwebtoken");*/
const { User } = require("../models/User");
module.exports.signup = async (req, res) => {
try {
const user = await User.create({
nom: "Jp",
prenom: "remy",
email: "remy#gmail.fr",
password: "motdepasse",
});
res.status(200);
throw Error("erreur est survenu");
} catch (erreur) {
console.log(erreur);
res.status(200).json({ erreur });
}
};
My route user
const express = require("express");
const router = express.Router();
const userCtrl = require("../controllers/user");
router.post("/signup", userCtrl.signup);
/*router.post("/login", userCtrl.login);*/
module.exports = router;
Thank you for any help! :)
The answer was that on my model user the "S" of sequelize must have an s minus
Related
I'm being driven slowly mad by this issue.
Using a local Apollo Server instance being accessed by Apollo Studio, I am attempting a simple mutation, createUser, and this issue is arising. What have I misunderstood?
Am I incorrectly consuming the context I provided in the server's creation? Or incorrectly accessing this model, maybe? Not sure!
Here is the error showing in Apollo Studio, followed by my files:
{
"errors": [
{
"message": "Cannot read properties of undefined (reading 'findOne')",
"locations": [
{
"line": 2,
"column": 3
}
],
"path": [
"createUser"
],
"extensions": {
"code": "INTERNAL_SERVER_ERROR",
"exception": {
"stacktrace": [
"TypeError: Cannot read properties of undefined (reading 'findOne')",
" at Object.createUser (/Volumes/T7 Touch/Projects/PassTheArt/pass-the-art-server/graphql/resolvers/user.js:22:46)",
" at field.resolve (/Volumes/T7 Touch/Projects/PassTheArt/pass-the-art-server/node_modules/apollo-server-core/dist/utils/schemaInstrumentation.js:56:26)",
" at executeField (/Volumes/T7 Touch/Projects/PassTheArt/pass-the-art-server/node_modules/graphql/execution/execute.js:479:20)",
" at /Volumes/T7 Touch/Projects/PassTheArt/pass-the-art-server/node_modules/graphql/execution/execute.js:375:22",
" at promiseReduce (/Volumes/T7 Touch/Projects/PassTheArt/pass-the-art-server/node_modules/graphql/jsutils/promiseReduce.js:23:9)",
" at executeFieldsSerially (/Volumes/T7 Touch/Projects/PassTheArt/pass-the-art-server/node_modules/graphql/execution/execute.js:371:43)",
" at executeOperation (/Volumes/T7 Touch/Projects/PassTheArt/pass-the-art-server/node_modules/graphql/execution/execute.js:345:14)",
" at execute (/Volumes/T7 Touch/Projects/PassTheArt/pass-the-art-server/node_modules/graphql/execution/execute.js:136:20)",
" at execute (/Volumes/T7 Touch/Projects/PassTheArt/pass-the-art-server/node_modules/apollo-server-core/dist/requestPipeline.js:205:48)",
" at processGraphQLRequest (/Volumes/T7 Touch/Projects/PassTheArt/pass-the-art-server/node_modules/apollo-server-core/dist/requestPipeline.js:148:34)"
]
}
}
}
],
"data": null
}
// ./server.js
require('dotenv').config();
import express from 'express';
import db from './db';
import resolvers from './graphql/resolvers';
import typeDefs from './graphql/typeDefs';
import http from 'http';
import { ApolloServer } from 'apollo-server-express';
async function startApolloServer(){
const server = new ApolloServer({
typeDefs,
resolvers,
introspection: true,
playground: true,
context: async() => {
return {
db
}
}
});
const app = express();
const httpServer = http.createServer(app);
server.start().then(res=>{
server.applyMiddleware({app, path: '/graphql'});
db.sequelize.sync({force: true}).then(async()=>{
console.log('database synced');
});
httpServer.listen({port: process.env.PORT}, ()=>{
console.log(`Apollo Server is ready at http://localhost:${process.env.PORT}/graphql`)
})
})
}
startApolloServer();
// ./graphql/resolvers/user.js
import { UserInputError } from "apollo-server-express";
import { Op } from "sequelize";
export default {
Query: {
// ! This query is for the logged in user
me: async(root, args, {db, me}, info) => {
const user = await db.user.findByPk(me.id);
return user;
},
// ! This query returns all users
users: async(root, args, {db}, info) => {
const users = await db.user.findAll();
if (!users) throw new Error('No users found')
return users;
}
},
Mutation: {
// ! This mutation creates a new user
createUser: async(root, {input}, {db}) => {
const {email} = input;
const userExists = await db.user.findOne({
where: {
[Op.eq]: [{email}]
}
})
if (userExists) {
throw new Error('A user with this email already exists');
}
const user = await db.user.create({
...input
});
return user;
},
// !
login: async(root, {email, password}, {db}, info) => {
const user = await db.user.findOne({
where: {email},
});
if(!user) throw new UserInputError(`User ${email} does not exist`);
const isValid = await user.validatePassword(password);
if(!isValid) throw new UserInputError(`Password is incorrect`);
return user;
}
}
}
// ./db.js
require('dotenv').config();
import fs from 'fs';
import path from 'path';
import { Sequelize } from 'sequelize';
const basename = path.basename(__filename);
const db = {};
const sequelize = new Sequelize(
process.env.POSTGRES_DB,
process.env.POSTGRES_USER,
process.env.POSTGRES_PASSWORD,
{
host: process.env.POSTGRES_HOST,
port: process.env.POSTGRES_PORT,
dialect: 'postgres'
}
);
sequelize.authenticate()
.then(console.log(()=>'Connection has been established successfully.'))
.catch(e=>console.error('Unable to connect to the database:', e));
const modelPath = path.join(__dirname, '/models');
fs.readdirSync(path.join(modelPath))
.filter((file)=>
file.indexOf('.') !== 0 && file !== basename && file.slice(-3) === '.js'
)
.forEach((file)=>{
const model = sequelize.define(path.join(modelPath, 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;
// ./models/User.js
import bcrypt from 'bcryptjs';
export default (sequelize, DataTypes) => {
const User = sequelize.define(
'user',
{
name: {
type: DataTypes.STRING,
allowNull: false,
},
email: {
type: DataTypes.STRING,
allowNull: false,
unique: true,
validate: {
isEmail: {
args: true,
msg: 'Invalid email'
},
},
},
password: {
type: DataTypes.STRING,
allowNull: false,
},
},
{
freezeTableName: true,
},
);
User.findByLogin = async (login) => {
let user = await User.findOne({
where: {email: login},
});
return user;
};
User.beforeCreate(async (user) => {
if (user.password){
user.password = await user.generatePasswordHash();
}
});
User.prototype.updatePasswordHash = async function (password) {
const saltRounds = 10;
return await bcrypt.hash(password, saltRounds);
};
User.prototype.updatePasswordHash = async function () {
const saltRounds = 10;
return await bcrypt.hash(this.password, saltRounds);
};
User.prototype.validatePassword = async function (password) {
return await bcrypt.compare(password, this.password);
};
return User;
}
// ./graphql/typedefs/User.js
import { gql } from "apollo-server-express";
export default gql`
#---------------------------------------
# TYPES
#---------------------------------------
type User {
id: ID
name: String!
email: String!
}
#---------------------------------------
# QUERIES
#---------------------------------------
extend type Query {
me: User
users: [User!]
}
#---------------------------------------
# MUTATIONS
#---------------------------------------
extend type Mutation {
createUser(input: CreateUserInput!): User!
login(email: String!, password: String!): User!
logout: User!
}
#---------------------------------------
# MUTATIONS
#---------------------------------------
input CreateUserInput {
name: String!
email: String!
password: String!
}
`
You need to correct where option from
where: {
[Op.eq]: [{email}]
}
to
where: {
email
}
just like you did in the login mutation.
I managed to get db.user.findOne defined properly. I was not properly using sequelize.define() in db.js, and I have now rewritten the pesky section as such:
const modelPath = path.join(__dirname, '/models');
fs.readdirSync(path.join(modelPath))
.filter((file)=>
file.indexOf('.') !== 0 && file !== basename && file.slice(-3) === '.js'
)
.forEach((file)=>{
const modelFile = path.join(modelPath, file);
const modelExport = require(modelFile);
if (! modelExport) throw new Error ('Error accessing model declaration file: ', modelFile)
const model = modelExport.default(sequelize);
db[model.name] = model;
});
const express = require("express");
const router = express.Router();
const bcrypt = require("bcrypt");
const { Users } = require("../../models/Users");
router.post("/", async (req, res) => {
const { username, password } = req.body;
bcrypt.hash(password, 10).then((hash) => {
Users.create({
username: username,
password: hash,
});
res.json("SUCCESS");
});
});
models/Users.js
module.exports = (sequelize, DataTypes) => {
const Users = sequelize.define("Users", {
username: {
type: DataTypes.STRING,
allowNull: false,
},
password: {
type: DataTypes.STRING,
allowNull: false,
},
});
return Users;
};
Hello i have problem with creating user in my db. The error is TypeError: Cannot read properties of undefined (reading 'create'). I dont know what is wrong. Help me please.
Your models/Users.js module exports a function, not the Users object that you need. Instead of having sequelize and DataTypes as function parameters, you should require them in the module:
const {sequelize, DataTypes} = require("sequelize");
module.exports = {
Users: sequelize.define("Users", {
...
})
};
I am creating realtionship (one to many) between User model and Task model
I have crated the reference column in the migration too
I am using sequlize ORM with sequelize cli. Everything works fine when I try alternative method that i will explain later but If i try to do it according the documentation it gives me error
Task is not associated to User
WORKING ALTERNATIVE METHOD
IN end of index.js file I created relations and it works as expected
db.user = require("../models/user.js")(sequelize, Sequelize);
db.tasks = require("../models/Task.js")(sequelize, Sequelize);
db.user.hasMany(db.tasks, { as: "user_tasks",foreignKey: "userId" });
db.tasks.belongsTo(db.user, {
foreignKey: "userId",
as: "task_user",
});
but when i follow the documetation i got error that i mentioned earlier
According to document
Model User.js
module.exports = (sequelize, DataTypes) => {
const User =sequelize.define('User',{
id: {
type: DataTypes.INTEGER,
autoIncrement: true,
allowNull: false,
primaryKey: true,
},
name: {
type: DataTypes.STRING,
allowNull: false,
},
age: {
type: DataTypes.INTEGER,
},
email: {
type: DataTypes.STRING,
},
createdAt: {
allowNull: false,
type: DataTypes.DATE
},
updatedAt: {
allowNull: false,
type: DataTypes.DATE
}
});
User.associate = (models) =>{
User.hasMany(models.Tasks, {
as: 'user_tasks',
foreignKey: 'userId'}
);
};
return User;
};
Model: Task.js
module.exports = (sequelize, DataTypes) => {
const Task = sequelize.define('Task', {
id: {
type: DataTypes.INTEGER,
autoIncrement: true,
allowNull: false,
primaryKey: true,
},
title: {
type: DataTypes.STRING,
allowNull: false,
},
userId: {
type: DataTypes.INTEGER,
},
});
Task.associate = function(models) {
Task.belongsTo(models.User, {
as:'owner',
foreignKey:'userId',
onDelete: "cascade"
});
};
return Task;
}
This is how i am trying to get data from database
controller
const User = db.user
const {Tasks} = db.tasks
exports.usertasks = async(req,res)=>{
// const users = await User(db.sequelize,db.Sequelize).findAll({
const users = await User.findAll({
include:[{model:Tasks,as:"user_tasks"}]
});
res.json(users)
console.log("All users with their associated tasks:", JSON.stringify(users, null, 4));
}
My Index.js file
'use strict';
const fs = require('fs');
const path = require('path');
const Sequelize = require('sequelize');
const basename = path.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);
}
fs
.readdirSync(__dirname)
.filter(file => {
return (file.indexOf('.') !== 0) && (file !== basename) && (file.slice(-3) === '.js');
})
.forEach(file => {
const model = require(path.join(__dirname+'../models/', file))(sequelize, Sequelize.DataTypes);
console.log(model);
db[model.name] = model;
});
Object.keys(db).forEach(modelName => {
if (db[modelName].associate) {
db[modelName].associate(db);
}
});
db.sequelize = sequelize;
db.Sequelize = Sequelize;
//relations THIS IS WORKING AND I AM JUST CURIOUS WHETHER TO USE THIS APPROACH OR NOT
// db.user = require("../models/user.js")(sequelize, Sequelize);
// db.tasks = require("../models/Task.js")(sequelize, Sequelize);
// db.user.hasMany(db.tasks, { as: "user_tasks",foreignKey: "userId" });
// db.tasks.belongsTo(db.user, {
// foreignKey: "userId",
// as: "task_user",
// });
module.exports = db;
I am also attaching the picture of successful response that I get with the alternative method.
Kindly, guide whether the alternative method that I used is acceptable or should I stick to the documenation one?
.associate is not a native Model's method, so you need to call it manually.
I think in your index.js you want to do something like:
'use strict';
const Sequelize = require('sequelize');
const config = require('../config/config.json')[process.env.NODE_ENV || 'development'];
const requireAll = require('require-all');
const sequelize = config.use_env_variable
? new Sequelize(process.env[config.use_env_variable], config)
: new Sequelize(config.database, config.username, config.password, config);
const db = { sequelize };
const modelsInitializers = Object.values(requireAll({
dirname: __dirname,
recursive: false,
filter: (name) => name !== 'index.js' && name,
}));
const models = modelsInitializers.map((initializer) => {
const model = initializer(sequelize, Sequelize.DataTypes);
db[model.name] = model;
return model;
});
models.forEach((model) => {
if (model.associate) model.associate(db);
})
models.forEach((model) => {
if (model.associate) model.associate(models);
db[model.name] = model;
})
Object.entries().forEach(([modelName, model]) => {
model.associate(models);
db[modelName] = model;
});
module.exports = db;
I am implementing an E-Commerce site in NodeJS. I am using Sequelize for managing MySQL.
But I am getting an error while using getProducts() method.
The code of the function where I am using the getProducts() mehtod is as below
exports.postCart = (req, res, next) => {
const p_id = req.body.p_id;
// console.log(p_id);
let fetchedCart;
let newQuantity = 1;
req.user
.getCart()
.then((cart) => {
fetchedCart = cart;
console.log(p_id);
return cart.getProducts({ where: { id: p_id } });
})
.then((products) => {
let product;
if (products.length > 0) {
product = products[0];
}
if (product) {
// ....
}
return Product.findByPk(p_id)
})
.then((product) => {
return fetchedCart.addProduct(product, {
through: { quantity: newQuantity }
});
})
.then(() => {
res.redirect("/cart");
})
.catch((err) => {
console.log(err);
});
};
I am following a tutorial which I think is using an older version of sequelize. I am using 6.3.0 version of sequelize. So is the method getProducts() not available in sequelize 6 or an I am typing something wrong.
Any help is welcomed :D
Thanks in advance :)
Associations file
const http = require("http");
const path = require("path");
const express = require("express");
const bodyParser = require("body-parser");
const pageNotFoundController = require("./controllers/pageNotFound");
const sequelize = require("./util/database");
const Product = require('./models/product');
const User = require('./models/user');
const Cart = require('./models/cart');
const CartItem = require('./models/cart-item');
const app = express();
app.set("view engine", "ejs");
app.set("views", "views");
const adminRoutes = require("./routes/admin");
const shopRoutes = require("./routes/shop");
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static(path.join(__dirname, "public")));
app.use((req, res, next) => {
User.findByPk(1)
.then(user => {
req.user = user;
next();
})
.catch(err => {
console.log(err);
});
});
app.use("/admin", adminRoutes);
app.use(shopRoutes);
app.use(pageNotFoundController.getPageNotFound);
Product.belongsTo(User, {constraints: true, onDelete: 'CASCADE'});
User.hasMany(Product);
User.hasOne(Cart);
Cart.belongsTo(User);
Cart.belongsToMany(Product, { through: CartItem });
Product.belongsToMany(Cart, { through: CartItem });
sequelize
// .sync({ force: true })
.sync()
.then((result) => {
return User.findByPk(1);
// console.log(result);
})
.then(user => {
if (!user) {
User.create({name: "Prerak", email: "pmp.tech2000#gmail.com"});
}
return user;
})
.then(user => {
console.log(user);
})
.then(cart => {
app.listen(3000);
})
.catch((err) => {
console.log(err);
});
Models file
model - cart.js
const Sequelize = require('sequelize')
const sequelize = require('../util/database')
const Cart = sequelize.define('cart', {
id: {
type: Sequelize.INTEGER,
autoIncrement: true,
allowNull: false,
primaryKey: true
}
});
module.exports = Cart;
model - cart-item.js
const Sequelize = require("sequelize");
const sequelize = require("../util/database");
const CartItem = sequelize.define("cartItem", {
id: {
type: Sequelize.INTEGER,
autoIncrement: true,
allowNull: false,
primaryKey: true,
},
quantity: {
type: Sequelize.INTEGER,
},
});
module.exports = CartItem;
model - product.js
const Sequelize = require("sequelize");
const sequelize = require("../util/database");
const Product = sequelize.define("product", {
id: {
type: Sequelize.INTEGER,
autoIncrement: true,
allowNull: false,
primaryKey: true,
},
title: Sequelize.STRING,
price: {
type: Sequelize.DOUBLE,
allowNull: false,
},
imageUrl: {
type: Sequelize.STRING,
allowNull: false,
},
description: {
type: Sequelize.STRING,
allowNull: false,
},
});
module.exports = Product;
model - user.js
const Sequelize = require("sequelize");
const sequelize = require("../util/database");
const User = sequelize.define("user", {
id: {
type: Sequelize.INTEGER,
autoIncrement: true,
allowNull: false,
primaryKey: true,
},
name: {
type: Sequelize.STRING,
allowNull: false,
},
email: {
type: Sequelize.STRING,
allowNull: true,
},
});
module.exports = User;
i try to change my Db from mongodb to mysql, i use sequelize instead of mongoose, and i got this error, i created the User.js model with sequelize format, but something wrong and i don't know why
const User = sequelize.define('users', {
^
TypeError: Cannot read property 'define' of undefined"
Here is my code:
server.js
const Sequelize = require('sequelize');
// DB Config
const db = require('./config/keys');
// Connect to MySql
const sequelize = new Sequelize(db.database, db.user, db.password, {
host: db.host,
dialect: 'mysql',
port: db.port
});
// Test the connection
sequelize
.authenticate()
.then(() => {
console.log('Connection has been established successfully.');
})
.catch(err => {
console.error('Unable to connect to the database:', err);
});
const serverDB = {};
serverDB.sequelize = sequelize;
serverDB.Sequelize = Sequelize;
module.exports = serverDB;
Users.js
const serverDB = require('../server');
const sequelize = serverDB.sequelize;
const Sequelize = serverDB.Sequelize;
const User = sequelize.define('users', {
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
},
avatar: {
type: STRING
},
date: {
type: Sequelize.DATE,
defaudefaultValue: Sequelize.NOW
}
});
sequelize.models.modelName
// sequelize.sync()
// .then(() => {
// console.log('User db and user table have been created')
// });
module.exports = User;
You should add
const Sequelize = require('sequelize');
in your client too.
And only export and use the lowercase sequelize.
And ensure relative path of server.js is good.