In expressJs project, I try to use sequelize to interact with database.
This is my model/user.js :
module.exports = (sequelize, DataTypes) => {
sequelize.define('user', {
email: {
type: DataTypes.STRING,
unique: true
},
password: DataTypes.STRING
})
}
And this is models/index.js :
const fs = require('fs')
const path = require('path')
const Sequelize = require('sequelize')
const config = require('../config/config')
const db = {}
const sequelize = new Sequelize(
config.db.database,
config.db.user,
config.db.password,
config.db.options
)
fs
.readdirSync(__dirname)
.filter((file) =>
file !== 'index.js'
)
.forEach((file) => {
var a = path.join(__dirname, file);
const model = sequelize.import(path.join(__dirname, file));
db[model.name] = model;
})
db.sequelize = sequelize
db.Sequelize = Sequelize
module.exports = db
The problem is in this line
const model = sequelize.import(path.join(__dirname, file));
Which returns undefine to model variable.
What did I miss here? I appreciate any hint?
Whole code on Github : here
Problem could be because of a missing return
module.exports = (sequelize, DataTypes) => {
const User = sequelize.define('User', { // Missing return
email: {
type: DataTypes.STRING,
unique: true
},
password: DataTypes.STRING
})
}
Change to
module.exports = (sequelize, DataTypes) => {
const User = sequelize.define('User', {
email: {
type: DataTypes.STRING,
unique: true
},
password: DataTypes.STRING
});
return User;
}
Related
When I'm uploading data about my new user I don't get any information back with the new json file where is saved my user, I only get '{}' and that's all. I'm sending here my code and what I get in Postman.
index.js
const express = require('express');
const app = express();
const dotenv = require('dotenv');
dotenv.config();
const userRoute = require("./routes/user");
const authRoute = require("./routes/auth");
const mongoose = require('mongoose');
const { CLIENT_RENEG_LIMIT } = require('tls');
const { application } = require('express');
mongoose
.connect(process.env.MONGO_URL)
.then(() => console.log('Connected to Mongoose server'))
.catch((err) => {
console.log(err);
});
app.use(express.json());
app.use('/api/users', userRoute);
app.use('/api/auth', authRoute);
app.listen(process.env.PORT || 5200, ()=>{
console.log('Listening on port 5200');
});
auth.js
const router = require('express').Router();
const user = require('../models/user');
//REJESTRACJA
router.post('/rejestracja', async (req, res)=>{
const newUser = new user({
username: req.body.username,
email: req.body.email,
password: req.body.password,
});
try{
const saveduser = newUser.save();
res.status(201).json(saveduser);
}catch(err){
res.status(500).json(err);
}
});
module.exports = router
user.js
const mongoose = require('mongoose');
const {Boolean} = require('webidl-conversions');
const UserSchema = new mongoose.Schema({
username: { type: 'string', unique: true, required: true},
email: { type: 'string', unique: true, required: true},
password: { type: 'string', required: true, unique: true},
admin: { type: 'Boolean', default: false},},
{timestamps: true}
)
module.exports = mongoose.model('User', UserSchema);
postman screenshot
I am working with Express JS and Sequelize which is connected to a MSSQL database. I am unable to perform any requests as I am getting the error "Cannot read properties of undefined (reading 'findAll')". Can anyone help out with this one?
Below is my set up:
Invites Model:
module.exports = (sequelize, DataTypes) => {
const Invites = sequelize.define("Invites", {
Id: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true
},
Recipient: {
type: DataTypes.STRING,
allowNull: false,
validate: {
notEmpty: true
}
},
Code: {
type: DataTypes.INTEGER,
allowNull: false,
validate: {
notEmpty: true
}
},
Score: {
type: DataTypes.INTEGER,
allowNull: false,
validate: {
notEmpty: true
}
},
Status: {
type: DataTypes.INTEGER,
allowNull: false,
validate: {
notEmpty: true
}
},
Created: {
type: DataTypes.DATE,
allowNull: false,
validate: {
notEmpty: true
}
},
ExpiresOn: {
type: DataTypes.DATE,
allowNull: false,
validate: {
notEmpty: true
}
}
});
return Invites;
};
inviteController:
const { invitesModel } = require('../models/Invites');
const getAllInvites = (req, res) => {
invitesModel.findAll().then((invites) => {
res.send(invites);
}).catch((err) => {
console.log(err);
})
};
module.exports = {
getAllInvites,
}
index.js:
const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const cors = require('cors');
require('dotenv').config();
const db = require('./models');
const invitesController = require('./controllers/inviteController');
const cookieParser = require('cookie-parser');
const PORT = process.env.PORT || 5000;
app.use(cors()); //Cross origin resource sharing
app.use(express.json());
app.use(bodyParser.urlencoded({extended: false}));
app.use(cookieParser());
//Get invite data
app.route('/api/invites').get(invitesController.getAllInvites);
db.sequelize.sync().then((req) => {
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});
});
/models/index.js:
'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, 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;
The require statement '../models/Invites' does not return an object with an invitesModel property.
You probably want to change your import statement to:
const { Invites } = require('../models');
And then use
Invites.findAll(...);
to query the Invites model.
If you're not sure what a require statement is grabbing, you can add a log statement to check:
const modelsObj = require('../models');
console.log(Object.keys(modelObj); // or console.log(JSON.stringify(modelsObj);
try add '?'
const getAllInvites = (req, res) => {
invitesModel?.findAll()?.then((invites) => {
res.send(invites);
}).catch((err) => {
console.log(err);
})
};
Trying to create signin and signup using express and MongoDB. In postman the data is perfectly passed but couldn't save the data into mongoDB cluster.
IN this file connection to the db is created and also confused whether i am connected to the db or not in this file, I created schema for the user details to be provided
//Index.js
const express = require("express");
const mongoose = require("mongoose");
const app = express();
const dotenv = require("dotenv");
dotenv.config();
const db = process.env.DATABASE;
mongoose.connect(db, { useNewUrlParse: true }, () =>
console.log("connected to db")
);
//midlewares
app.use(express.json());
//importing routes
const authRoute = require("./routes/auth");
//route middle wares
app.use("/api/user", authRoute);
app.listen(3000, () => console.log("gg server is running"));
//User.js
const mongoose = require("mongoose");
const { Schema } = mongoose;
const userSchema = new Schema({
name: {
type: String,
max: 32,
required: true,
min: 6,
},
email: {
type: String,
required: true,
max: 32,
},
password: {
type: String,
max: 1022,
min: 8,
required: true,
},
date: {
type: Date,
default: Date.now,
},
});
module.exports = mongoose.model("User", userSchema);
//Auth.js
const router = require("express").Router();
const User = require("../model/User");
router.post("/register", (req, res) => {
const user = new User({
name: req.body.name,
email: req.body.email,
password: req.body.password,
});
const name = {
name: req.body.name,
email: req.body.email,
};
res.send(user);
user.save();
});
module.exports = route[![enter image description here][1]][1]r;
Step 1
First, you should create a server after your MongoDB is connected. So, put your server logic inside mongoose.connect connect. This will assure that when yo u try to create a new user, MongoDB is already connected.
mongoose.connect(db, { useNewUrlParse: true }, () =>
console.log("connected to db");
//midlewares
app.use(express.json());
//importing routes
const authRoute = require("./routes/auth");
//route middle wares
app.use("/api/user", authRoute);
app.listen(3000, () => console.log("gg server is running"));
);
Step 2
Use create method to create new user document:
router.post("/register", async (req, res) => {
const user = await User.create({
name: req.body.name,
email: req.body.email,
password: req.body.password,
});
return res.status(200).json(user);
});
Is it okay if I make models from copy-pasting? For instance, I made my first model User through Sequelize's model:generate. And then for other models, I just copy-pasted everything from the User model to my new models.
When doing db sync:
db.sequelize.sync({ force : true}).then(() => {
console.log("Drop and re-sync db.")
})
The new models won't create new tables. So I'm thinking copy-pasting for new models won't work. Is this right?
User model:
'use strict';
module.exports = (sequelize, DataTypes) => {
const User = sequelize.define('User', {
id: { type: DataTypes.BIGINT, allowNull: false, unique: true, primaryKey: true },
fbid: { type: DataTypes.BIGINT, allowNull: false, unique: true },
email: DataTypes.STRING,
first_name: DataTypes.STRING,
last_name: DataTypes.STRING,
photo_url: DataTypes.STRING
}, {});
User.associate = function(models) {
// associations can be defined here
};
return User;
};
And generated from copy-paste + modification of user model, I have: Country model
'use strict';
module.exports = (sequelize, DataTypes) => {
const Country = sequelize.define('Country', {
country_name: DataTypes.STRING
}, {});
Country.associate = function(models) {
// associations can be defined here
};
return Country;
};
Index.js generated by the cli in my models:
'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')[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 = sequelize['import'](path.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;
module.exports = db;
Then after the generated models, after executing model:generate I transferred the generated User.js into a User folder. Then do the copy-paste, not sure if moving the files affect the registering of the models I created by copy-paste.
Based on the comments above, I realized that my index.js file (generated by Sequelize) wasn't looking for model files that ARE placed in subfolders. Instead, it ONLY looks for the model files that are in the root folder - same level of the index.js file.
So I posted this question: Javascript get all files in a folder that are inside another fold
I had to use the package glob to make the index.js file look for subfolders too.
So my index.js's content is now:
'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')[env];
const db = {};
const glob = require("glob")
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);
}
const files = glob.sync(__dirname + "/*/*.js")
files.forEach(file => {
const model = sequelize['import'](file);
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;
To answer the specific question, NO. I don't have to do the commands all the time. I can copy-paste-edit new models instead.
This is the parent model/table:
const { Sequelize, DataTypes } = require('sequelize');
const VerifyToken = require('./verifyToken');
module.exports = (sequelize, DataTypes) => {
const User = sequelize.define('User', {
password: DataTypes.STRING,
email: DataTypes.STRING,
}, {
tableName: 'users',
timestamps: false,
//syncOnAssociation: true
hierarchy: true,
underscored: true
});
User.associate = function (models) {
const {VerifyToken} = models;
User.hasOne(VerifyToken, {
as: 'verify_tokens',
foreign_key: 'user_id'
});
};
return User;
};
This is the child model:
const User = require('./user');
module.exports = (sequelize, DataTypes) => {
const VerifyToken = sequelize.define('VerifyToken', {
user_id: DataTypes.INTEGER,
token: DataTypes.STRING,
}, {
tableName: 'verify_tokens',
hierarchy: true,
underscored: true
});
VerifyToken.associations = function (models) {
const {User} = models;
VerifyToken.belongsTo(User);
};
return VerifyToken;
};
models/index.js file:
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 = sequelize['import'](path.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;
module.exports = db;
, but when I make a query like this:
const verifyToken = await models.VerifyToken.findOne({
where: {
token
},
include:{
model: models.User
}
});
I am getting this:
SequelizeEagerLoadingError: User is not associated to VerifyToken!
Please correct VerifyToken.associations with VerifyToken.associate
Remove a redundant import of const VerifyToken = require('./verifyToken'); from the User model definition.