Sequelize findAll() or findOne is not working - express

I apologize for something that could be very simple to fix, I just cannot figure it out. I've used this code in another project before with the exact same layout and that project works, but on this project, it's not working.
As seen below in the code, I am doing a simple findAll() query. The database is connected perfectly fine but I keep getting this error no matter what I try.
[Error is here][1]
I wanted to double-check to see if it's because of me or if it's an issue with the latest release of sequelize, but I doubt it because I haven't seen any issues like this pop up yet.
But if nobody can see an issue, I will submit a bug ticket.
root/routes/ShopItems.js
const express = require('express')
const router = express.Router()
const { ShopItems } = require('../models')
router.get('/', async(req, res) => {
const data = await ShopItems.findAll()
res.json(data)
})
module.exports = router
root/index.js
const express = require('express')
const session = require('express-session')
const app = express()
const cors = require('cors')
const db = require('./models')
const { SECRET, PORT } = require('./temp_secret')
app.use(express.json())
app.use(cors())
app.use(session({
secret: SECRET,
resave: true,
saveUninitialized: false,
}))
app.use(express.urlencoded({extended: false}))
app.all('/*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*")
res.header("Access-Control-Allow-Headers", "X-Requested-With,GET,POST,content-type,Origin,Accept")
req.header("Access-Control-Allow-Origin", "*")
req.header("Access-Control-Allow-Headers", "X-Requested-With,GET,POST,content-type,Origin,Accept")
next()
})
// Routers
const ShopItemsRouter = require('./routes/ShopItems')
app.use('/shop', ShopItemsRouter)
db.sequelize.sync().then(() => {
app.listen(PORT, () => {
console.log(`Running on ${PORT}`)
})
})
root/models/index.js
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;
root/models/ShopItems.js
module.exports = (sequelize, DataTypes) => {
const ShopItems = sequelize.define('shop_items', {
item_name: {
type: DataTypes.STRING(),
allowNull: false
},
item_description: {
type: DataTypes.STRING(),
allowNull: false
},
item_type: {
type: DataTypes.STRING(),
allowNull: false,
defaultValue: 'Single Item'
},
item_categories: {
type: DataTypes.JSON(),
allowNull: false,
defaultValue: '{}'
},
item_genres: {
type: DataTypes.JSON(),
allowNull: false,
defaultValue: '{}'
},
initial_item_price: {
type: DataTypes.INTEGER(),
allowNull: false,
defaultValue: 0
},
item_discount: {
type: DataTypes.INTEGER(),
allowNull: false,
defaultValue: 0
},
item_price: {
type: DataTypes.INTEGER(),
allowNull: false,
defaultValue: 0
},
number_of_sales: {
type: DataTypes.INTEGER(),
allowNull: false,
defaultValue: 0
}
})
return ShopItems
}
Thank you anyone that helps, I greatly appreciate it.
[1]: https://i.stack.imgur.com/zBOTE.png

In the ShopItems routes file you have
const { ShopItems } = require('../models')
The problem with this is that the index.js file (Which is what gets brought in with the above statement), does not export a ShopItems property. This is why your error message is saying "Cannot read properties of undefined", because in this case the ShopItems variable is returning undefined.
Without seeing your ShopItems model I can't say for sure if this will work, but if that model exists and is set up properly, you should be able to do:
const db = require('../models')
And then inside of the route method:
const data = await db.ShopItems.findAll()

Related

how to handle image upload in the mern stack using multer?

Im creating a MERN stack application and in the react front end, i intend to have a form to add a product, the form is going to have a lot of inputs including an image upload option. I want to know how to handle the image upload from the express side using Multer. i have used their documentation but im not sure whether the code i wrote is correct. I also haven't created the front end yet, so i am currently using postman to test the api. How do i test whether the image upload functionality is working using postman? I would be posting the code i have written so far for context.
Product model:
const mongoose = require('mongoose')
const ProductSchema = new mongoose.Schema({
name:{
type: String,
required: [true, 'please provide a product name'],
maxlength: 20,
minlength: 3
},
category: {
type: String,
required: [true, 'please provide a category'],
maxlength: 20,
minlength: 3
},
quantity: {
type: Number,
required: [true, 'please provide the quantity']
},
price: {
type: Number,
required: [true, 'please provide the price']
},
description: {
type: String,
required: [true, 'please provide the description'],
trim: true
},
image: {
type: String
},
createdBy: {
type: mongoose.Types.ObjectId,
ref: 'User',
required: [true, 'Please provide the user'],
}, },
{ timestamps: true } )
module.exports = mongoose.model('Product', ProductSchema)
file upload.js:
const multer = require('multer')
const { v4: uuidv4 } = require('uuid')
const storage = multer.diskStorage({
destination: function(req, file, cb) {
cb(null, '../uploads')
},
filename: function(req, file, cb){
cb(null, uuidv4() + '-' + Date.now() + path.extname(file.originalname) )
}
})
const fileFilter = (req, file, cb) => {
const allowedTypes = ['image/jpeg', 'image/jpg', 'image/png']
if(allowedTypes.includes(file.mimetype)) {
cb(null, true)
}else(
cb(null, false)
)
}
const upload = multer({storage, fileFilter})
module.exports = upload
Product router:
const express = require('express')
const router = express.Router()
const upload = require('../utils/fileUpload')
const {getAllProducts, createProduct, getProduct, updateProduct, deleteProduct} = require('../controllers/products')
router.route('/').post(upload.single('image'), createProduct).get(getAllProducts)
router.route('/:id').get(getProduct).patch(updateProduct).delete(deleteProduct)
module.exports = router
Product controller:
const Product = require('../models/Product')
const { StatusCodes } = require('http-status-codes')
const { BadRequestError, NotFoundError } = require('../errors')
const createProduct = async (req, res) => {
req.body.createdBy = req.user.userId
const product = await Product.create({...req.body, image: req.file})
res.send('create Product')
}
const getAllProducts = async (req, res) => {
res.send('get All products')
}
const getProduct = async (req, res) => {
res.send('get product')
}
const updateProduct = async (req, res) => {
res.send('update product')
}
const deleteProduct = async (req, res) => {
res.send('delete product')
}
module.exports = {
getAllProducts, createProduct, getProduct, updateProduct, deleteProduct
}
You can change the parameter type to file from postman to try uploading files when sending a request :

WebRTC connectiong only send one candidate

I am new coding in Javascript.
I am creating a WebRTC connection between my iPhone and my browser.
The connection works but my code only send one candidate and I don't know if I am doing anything wrong. I would appreciate any comment or support.
Thanks
const createPeerConnection = (signaling) => {
const peerConnection = new RTCPeerConnection({
iceServers: [],
});
const offerOptions = {
offerToReceiveVideo: true, offerToReceiveAudio: true
};
peerConnection.createOffer(offerOptions);
createAndSendOffer(signaling, peerConnection);
peerConnection.onicecandidate = (iceEvent) => {
if (iceEvent && iceEvent.candidate) {
signaling.send(JSON.stringify({
type: MESSAGE_TYPE.IceCandidate,
payload: iceEvent.candidate,
}));
}
};
peerConnection.onconnectionstatechange = (state ) => {
console.log(peerConnection.connectionState);
};
return peerConnection;
};
const createAndSendOffer = async (signaling, peerConnection) => {
const offer = await peerConnection.createOffer();
await peerConnection.setLocalDescription(offer);
signaling.send(JSON.stringify({ type: MESSAGE_TYPE.SessionDescription, payload: offer }));
};

Restarting express server in esbuild

I am trying to create a simple express server with esbuild. These are my code
import express from "express";
const app = express();
const port = 3000;
const stopServer = {
stop: () => {},
};
export const createServer = async () => {
app.get("/", async (req, res) => {
res.json({
first: "Hello",
});
});
const server = app.listen(port, () => {
console.log(`Listening on port: ${port}`);
});
stopServer.stop = () => {
server.close();
};
};
export const stop = () => {
stopServer.stop();
stopServer.stop = () => {};
};
esbuild.config.js
const esbuild = require("esbuild");
const path = require("path");
const restartPlugin = () => {
return {
name: "restart-express",
setup(build) {
build.onEnd(async (res) => {
const { stop, createServer } = await import("../dist/server.js");
stop();
createServer();
});
},
};
};
const run = async () => {
await esbuild.build({
entryPoints: [path.resolve(__dirname, "../src/server.ts")],
outdir: path.resolve(__dirname, "../dist"),
platform: "node",
sourcemap: true,
format: "cjs",
watch: {
onRebuild: async (err, res) => {
if (err) {
console.error(err);
} else {
console.log("There is some change");
}
},
},
plugins: [restartPlugin()],
});
};
run();
Reference for plugin : https://github.com/evanw/esbuild/issues/1258#issuecomment-834676530
If you were to run this application It i will work initially but when you change the code, the server wont get updated even if you refresh the page.
I am not really sure where I am making mistake, Any help please
The problem is that node cache the import("..dist/server.js"), as a result it will never return new module. To solve this problem we will write a function
const purgeAppRequireCache = (buildPath) => {
for (let key in require.cache) {
if (key.startsWith(buildPath)) {
delete require.cache[key];
}
}
};
Which will remove the cache from the node. We can also use this function in this manner. Which solves my problem
const esbuild = require("esbuild");
const path = require("path");
const startPlugin = () => {
return {
name: "startPlugin",
setup(build) {
build.onEnd((res) => {
const serverPath = path.resolve(__dirname, "../dist/server.js");
const { stop } = require("../dist/server.js");
stop();
purgeAppRequireCache(serverPath);
purgeAppRequireCache(path.resolve(__dirname, "../src"));
const { listen } = require("../dist/server");
listen();
});
},
};
};
const run = async () => {
await esbuild.build({
entryPoints: [path.resolve(__dirname, "../src/server.tsx")],
outdir: path.resolve(__dirname, "../dist"),
platform: "node",
sourcemap: true,
format: "cjs",
watch: true,
bundle: true,
plugins: [startPlugin()],
});
};
run();
const purgeAppRequireCache = (buildPath) => {
for (let key in require.cache) {
if (key.startsWith(buildPath)) {
delete require.cache[key];
}
}
};
If you not reload runtime, the global's object and sub require(xxx) maby have same error.
You can use kill and fork cluster when change you code, it's same fast like require(xxx), there have example codes: https://github.com/ymzuiku/bike/blob/master/lib/index.js
If you need see kill and fork cluster example, here's a same feature package, also use esbuild, but it use fs.watch: https://www.npmjs.com/package/bike
Hope there could help you :)
#es-exec/esbuild-plugin-serve or #es-exec/esbuild-plugin-start are two alternative esbuild plugins that you can try. They run your bundles or any command line script for you after building your project (supports watch mode for rebuilding on file changes).
The documentation can be found at the following:
#es-exec/esbuild-plugin-serve
#es-exec/esbuild-plugin-start
Disclaimer: I am the author of these packages.

Getting Error 500 (general-error) while uploading files in feathersjs

I am getting this error on Postman when I send request for uploading files on Feathersjs:
{
"name": "GeneralError",
"message": "ENOENT: no such file or directory, open 'public/uploads/pic'",
"code": 500,
"className": "general-error",
"data": {},
"errors": {}
}
My uploads.service.js:
const {Uploads} = require('./uploads.class');
const createModel = require('../../models/uploads.model');
const hooks = require('./uploads.hooks');
const multer = require('multer');
const storage = multer.diskStorage({
destination: (_req, _file, cb) => cb(null, 'public/uploads'), // where the files are being stored
filename: (_req, file, cb) => {
console.log(_req.body);
//cb(null, ${_req.body.name});
cb(null, `${_req.body.name}`); //
}, // getting the file name
});
const uploads = multer({
storage,
limits: {
fieldSize: 1e8,
fileSize: 1e7,
},
});
module.exports = function(app) {
const options = {
Model: createModel(app),
paginate: app.get('paginate'),
multi: true,
};
// Initialize our service with any options it requires
app.use(
'/uploads',
uploads.array('files'),
(req, _res, next) => {
const {method} = req;
if (method === 'POST' || method === 'PATCH') {
console.log(req.files);
console.log(req.body);
req.feathers.files = req.body.files;
const body = [];
for (const file of req.files)
body.push({
name: req.body.name,
newNameWithPath: file.path,
});
req.body = method === 'POST' ? body : body[0];
}
next();
},
new Uploads(options, app),
);
// Get our initialized service so that we can register hooks
const service = app.service('uploads');
service.hooks(hooks);
};
This is my uploads.model.js:
module.exports = function(app) {
const modelName = 'uploads';
const mongooseClient = app.get('mongooseClient');
const {Schema} = mongooseClient;
const schema = new Schema(
{
name: {type: String, required: true},
},
{
timestamps: true,
},
);
// This is necessary to avoid model compilation errors in watch mode
// see https://mongoosejs.com/docs/api/connection.html#connection_Connection-deleteModel
if (mongooseClient.modelNames().includes(modelName)) {
mongooseClient.deleteModel(modelName);
}
return mongooseClient.model(modelName, schema);
};
I really cannot figure out where exactly the problem is. According to me it is supposed to make the folder automatically when I upload the file.
I would really appreciate some help. Thank you in advance.
It was my own mistake. I made the uploads folder inside public folder myself and now it's working.

findOne is not a function

I am trying to create a model using Sequelize and mysql db.I am trying to post to '/students/register' it keeps giving me an error saying findOne is not a function. I tried requiring my sql but it's not working ..I also tried a different function like findAll and still not working.what seems to be the problem
const Sequelize = require('sequelize');
module.exports = function (sequelize, Sequelize) {
const Stundet = sequelize.define(
'student', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
},
name: {
type: Sequelize.STRING
},
email: {
type: Sequelize.STRING
},
password: {
type: Sequelize.STRING
},
created: {
type: Sequelize.DATE,
defaultValue: Sequelize.NOW
}
}, {
timestamps: false
});
module.exports = Stundet;
}
routes
const Student_Info = require("../models/students")
student.post('/register', (req, res) => {
const dataToday = new Date()
const studentData = {
name: req.body.name,
email: req.body.email,
password: req.body.password,
created: dataToday
}
Student_Info.findOne({
where: {
email: req.body.email
}
})
.then(student => {
if (!student) {
bcrypt.hash(req.body.password, 10, (err, hash) => {
studentData.password = hash
Student_Info.create(studentData)
.then(student => {
res.json({
status: student.email + 'registered'
})
})
.catch(err => {
res.send('error' + err)
})
})
} else {
res.json({
error: 'Student already registered'
})
}
})
.catch(err => {
res.send('error' + err)
})
})
module.exports = student;
When you use module.exports, you should return Stundet. You already export the whole function. And I think you should pass DataTypes instead of Sequelize.
Something like this:
module.exports = function (sequelize, DataTypes) {
const Stundet = sequelize.define(
//...
return Stundet;
}
So in your route in order to use your model:
const Sequelize = require('sequelize');
const DataTypes = sequelize.DataTypes;
let sequelize = new Sequelize(...);
const Student = require('../models/students')(sequelize, DataTypes);
I suspect that your Student_Info is null. Does you application successfully connect to the database? It helps to log... e.g.
sequelizeDB
.authenticate()
.then(() => {
console.log('Yes! DB Connection);
...
})
.catch(err => {
console.error('No! Unable to connect to DB', err);
});
... and IMHO the code reads better when you name the DB instance something other than "sequelize".