How to pass data from Helper Mysql Promises nodejs - javascript

i have a problem passing data from folder helper
database.js
const mysql = require('mysql2');
const pool = mysql.createPool({
host: 'localhost',
port:'3306',
user: 'root',
database: '',
password: '',
dateStrings: true
});
module.exports = pool.promise();
helper.js
const Master = require('../models/inspection');
module.exports = {
getLokasi: function (x) {
Master.fetchAll()
.then(([result]) => {
const hasil = result;
return hasil;
})
.catch(err => console.log(err));
}
}
model inspection.js
const db = require('../util/database');
module.exports = class Master {
constructor(si_id) {
this.si_id = si_id;
}
static fetchAll() {
return db.execute('SELECT * FROM mt_analisa_resiko');
}
};
controller
const helpers = require('../../util/helpers');
exports.getInspectionDetail = (req, res, next) => {
const test = helpers.getLokasi();
console.log(test);
}
the problem always return undefined
but when i console.log(hasil) on helper.js it return the data. How do i pass the data from helper so i can used the data on my controller.

You need to return the promise:
module.exports = {
getLokasi: function (x) {
return Master.fetchAll()
.then(([result]) => {
const hasil = result;
return hasil;
})
.catch(err => console.log(err));
}
}
You should be able to access the returned value then:
exports.getInspectionDetail = async (req, res, next) => {
const result = await helpers.getLokasi();
console.log(result);
}

Related

node.js send notification to specific user in controller

index.js file
var users = [];
let addUser = (userId, socketId) => {
!users.some((user) => user.userId === userId) &&
users.push({ userId, socketId });
};
let removeUser = (socketId) => {
users = users.filter((item) => item.socketId !== socketId);
};
const getUser = (userId) => {
console.log("inside function", users);
return users.find((item) => item.userId === userId);
};
io.on("connection", (socket) => {
socket.on("addUser", async (userId) => {
await addUser(userId, socket.id);
io.emit("getUsers", users);
console.log(users) // print array of users like this
// [{userId:'userId',socketId: 'socket id'}]
});
socket.on("disconnect", () => {
removeUser(socket.id);
io.emit("getUsers", users);
});
});
const socketIoObject = io;
const usersInObject = users;
module.exports.ioObject = { socketIoObject, usersInObject };
controller file
exports.createNotifications = async (req, res) => {
try {
const { userId, title, type = "default", isPublic } = req.body;
if (!title) {
return res.status(401).send("Data is required");
}
const notification = await notificationsModel.create({
userId,
title,
type,
isPublic: userId ? false : true,
});
console.log("socket", socket.ioObject.usersInObject); // return empty
// array [] !!!!
return res.status(200).send("sent");
} catch (err) {
return res.status(400).send(err.message);
}
};
why I can't get the users list in the controller, I got an empty array !!
I need to share the users list in all files to can get the user by function getUser to get the socketId of a specific user to can send a notification to him
Maybe, you import socket in controller file incorrect

Convert form data to JSON file with NodeJS

I have a project in Node JS in which I have a form to add new users.
How can I view this information in JSON format?
These are the data that I see:
name age country city
------------------------------
user1 22 Spain Madrid button{View JSON}
When I press the 'View JSON' button, the following must be displayed below the table:
[
"id": 1,
"name": "user1",
"age": 22,
"country": "Spain" {
"city":"Madrid"
}
]
My problem: how can I create a function that performs this conversion? How do I call the function from index.ejs?
I cleared and merged the codes. And I created a new endpoint as /export to export the data as CSV file. I couldn't test it so let me know if it doesn't work.
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
const MongoClient = require('mongodb').MongoClient;
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(express.static('public'));
app.set('views', './src/views');
app.get('/', async (req, res) => {
const db = await mongoDB();
const person = await db.collection('person').find().toArray();
res.render('index.ejs', { person: person })
})
app.get('/export', async (req, res) => {
await convertCSV();
res.status(200).send( { success: 1 });
})
app.post('/person', async (req, res) => {
res.redirect('/');
})
app.listen(process.env.PORT, function () {
console.log(`server: http://${process.env.HOST}:${process.env.PORT}`);
})
const mongoDB = () => {
return new Promise((resolve, reject) => {
const url = 'mongodb://127.0.0.1:27017';
MongoClient.connect(url, { useUnifiedTopology: true })
.then(client => {
const db = client.db('users')
resolve(db);
})
.catch(error => reject(error))
});
}
const convertCSV = () => {
return new Promise((resolve, reject) => {
const converter = require("json-2-csv");
const fetch = require("node-fetch");
const fs = require("fs");
const flatten = require('flat');
const maxRecords = 10;
const getJson = async () => {
const response = await fetch(`http://${process.env.HOST}:${process.env.PORT}/users.json`);
const responseJson = await response.json();
return responseJson;
};
const convertToCSV = async () => {
const json = await getJson();
let keys = Object.keys(flatten(json[0]));
let options = {
keys: keys
};
converter.json2csv(json, json2csvCallback, options);
};
let json2csvCallback = function (err, csv) {
if (err) throw err;
const headers = csv.split('\n').slice(0, 1);
const records = csv.split('\n').slice(0,);
for (let i = 1; i < records.length; i = i + maxRecords) {
let dataOut = headers.concat(records.slice(i, i + 3)).join('\n');
let id = Math.floor(i / maxRecords) + 1;
fs.writeFileSync('data' + id + '.csv', dataOut)
}
};
await convertToCSV();
resolve();
})
}
However, it is not a good practice at all to using controller, index and route in the same file. A better approach would be to create routes, controllers folders and put the codes in a more orderly form.
Something like this (You can find better ones of course mine is just advice):
- index.js
- router.js (A router to manage your endpoints)
- controllers (Controller when you call the endpoint)
-> export.controller.js
-> person.controller.js
- routes (Endpoints)
-> export.route.js
-> person.route.js
- helpers
-> databaseHandler.js (Database connection handler)

Unit testing middleware after express-validator

I have my routes.js like
app.get('/', userRules(), validate, mycontroller)
const { query } = require('express-validator');
module.exports = {
userRules: () => [query('team_id').optional().isInt(),
query('active_team').optional().isBoolean()],
};
and my validate function looks like
const { validationResult } = require('express-validator');
const { createMessage } = require('../helpers/index');
module.exports = {
validate: (req, res, next) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
const message = createMessage(errors.array());
return res.status(400).json({ error: true, message });
}
return next();
},
}
What I want to achieve is to UnitTest that validate function in order to understand the behaviour
const httpMocks = require('node-mocks-http');
const { userRules } = require('../../router/validation');
const { validateUsers } = require('../index');
it('should return a 400', () => {
const req = httpMocks.createRequest({
query: {
active_team: 'aaaa',
},
});
myStub(req, userRules());
const res = httpMocks.createResponse();
validateUsers(req, res, next);
expect(res.statusCode).toBe(400);
});
What I'm expecting is a 400 but I got a 200 and the next() function is getting called everytime
Is there any way to do this?
I know I can use supertest but I don't really want it.

How to fix sequelize connection issue while generating index.js?

I new in node.js and have some problems with sequelize-cli.
I have sequelize model and while I run the project, i get error in my index.js:
const model = require(path.join(__dirname, file))(sequelize, Sequelize.DataTypes);
TypeError: require(...) is not a function
The project can't find or read this (sequelize, Sequelize.DataTypes).
My project: server.js
const express = require("express");
const productRouter = require("./routers/productRouter");
const discountRouter = require("./routers/discountRouter")
const app = express();
const PORT = process.env.PORT || 3000;
app.use(express.json());
// Запрос на таблицу с продуктами
app.use("/shop", productRouter);
// Запрос на таблицу со скидками
app.use("/shop", discountRouter);
app.listen(PORT, () => console.log("Server is working ... "));
productRouter.js
const Router = require("express");
const router = new Router();
const productController = require("../controllers/productControllers");
// Получаем все товары
router.get("/products", async (req, res, next) => {
const resultOfGetAllProducts = await productController.all();
if(resultOfGetAllProducts === Error) {
return res.sendStatus(500).json(Error);
} else {
return res.sendStatus(200).json(resultOfGetAllProducts);
};
});
// Получаем конкретный товар
router.get("/product/:id", async (req, res, next) => {
if(!req.params.id) return res.sendStatus(400).send("Product ID is not specified.");
const id = req.params.id;
const result = null;
const resultOfGetOneProduct = await productController.one(id, result);
if(resultOfGetOneProduct === Error) {
return res.sendStatus(500).json(Error);
} else {
return res.sendStatus(200).json(resultOfGetOneProduct);
};
});
// Добавляем товар
router.post("/product", async (req, res, next) => {
if(!req.body) return res.sendStatus(400).send("Product parameters are not specified.");
const product = {
product_name: req.body.product_name,
price: req.body.price,
product_description: req.body.product_description
};
const result = null;
const resultOfCreateProduct = await productController.create(product, result);
if (resultOfCreateProduct === Error) {
return res.sendStatus(500).json(Error);
} else {
return res.sendStatus(200).send("The product has been created.");
}
});
// Обновляем товар
router.put("/product/:id", async (req, res, next) => {
if(!req.params.id) return res.sendStatus(400).send("Product ID is not specified.");
if(!req.body) return res.sendStatus(400).send("Product parameters are not specified.");
const product = {
product_name: req.body.product_name,
price: req.body.price,
product_description: req.body.product_description
}
const id = {id: req.params.id};
const result = null;
const resultOfUpdateProduct = await productController.update(id, product, result);
if(resultOfUpdateProduct === Error) {
return res.sendStatus(500).json(Error);
} else {
return res.sendStatus(200).send("The product has been updated.");
};
});
// Удаляем товар
router.delete("/product/:id", async (req, res, next) => {
if(!req.params.id) return res.sendStatus(400).send("Product ID is not specified.");
const id = {id: req.params.id};
const result = null;
const resultOfDeleteProduct = await productController.delete(id, result);
if(resultOfDeleteProduct === Error) {
return res.sendStatus(500).json(Error);
} else {
return res.sendStatus(200).send("The product has been deleted.");
}
});
module.exports = router;
productControllers.js
const productModels = require("../models/productModels");
exports.all = async function getAllProducts() {
const result = await productModels.all(function(err, docs) {
if (err) {
console.log(err);
return err;
} else {
return docs;
};
});
return result;
};
exports.one = async function getOneProduct(id, cb) {
const result = await productModels.one(id, function(err, doc) {
if (err) {
console.log(err);
return err;
} else {
return doc;
}
});
cb = result;
return cb;
};
exports.create = async function createProduct(product, cb) {
const confirmationOfCreate = await productModels.create(product, function(err, result) {
if (err) {
console.log(err);
return err;
} else {
return result;
}
});
cb = confirmationOfCreate;
return cb;
};
exports.update = async function updateProduct(id, product, cb) {
const confirmationOfUpdate = await productModels.update(id, product, function(err, result) {
if (err) {
console.log(err);
return err;
} else {
return result;
}
});
cb = confirmationOfUpdate;
return cb;
};
exports.delete = async function deleteProduct(id, cb) {
const confirmationOfDelete = await productModels.delete(id, function(err, result) {
if (err) {
console.log(err);
return err;
} else {
return result;
}
});
cb = confirmationOfDelete;
return cb;
};
productModels.js
const Sequelize = require("sequelize");
const productsModel = require("./products.js");
const db = require("./index.js");
// Получаю с бд все продукты
exports.all = async function getProducts(cb) {
//const products = await db.query('SELECT * FROM products');
const products = await db.findAll({raw: true});
if(products === null) {
return cb(Error, null);
} else {
return cb(null, products);
};
};
// Получаю с бд конкретный продукт
exports.one = async function getOneProduct(id, cb) {
//const getOneQuery = 'SELECT * FROM product where id = $1';
//const getDiscount = 'SELECT * FROM discounts where product_id = $1';
//const curDiscount = await Discount.findOne({where: id});
const product = await db.findAll({where: {id: id}});
const productDiscount = await Discount.findAll({where: {product_id: id}});
const priceWithDiscount = product.price - (product.price * ((productDiscount.discount)/100));
if (product === null) {
return cb(Error, null);
} else if(productDiscount === null) {
return cb(null, product)
} else {
product.price = priceWithDiscount;
const result = product;
return cb(null, result);
};
};
// Создаю в бд продукт
exports.create = async function createProduct(product, cb) {
// const createQuery = 'INSERT INTO product (product_name, price, product_description) values ($1, $2, $3) RETURNING *';
// const arrayQuery = [product.product_name, product.price, product.product_description];
// const newProduct = await db.query(createQuery, arrayQuery);
const newProduct = await db.create(product);
if(newProduct === null) {
return cb(Error, null);
} else {
return cb(null, newProduct);
};
};
// Обновляю в бд конкретный продукт
exports.update = async function updateProduct(id, newData, cb) {
// const updateQuery = 'UPDATE product set product_name = $1, price = $2, product_description = $3 where id = $4 RETURNING *';
// const arrayQuery = [newData.product_name, newData.price, newData.product_description, id];
const product = await db.update(newData, {where: id});
if(product === null) {
return cb(Error, null);
} else {
return cb(null, product);
};
};
// Удаляю в бд конкретный продукт
exports.delete = async function deleteProduct(id, cb) {
//const deleteQuery = 'DELETE FROM product where id = $1';
const product = await db.destroy({where: id});
if(product === null) {
return cb(Error, null);
} else {
return cb(null, product);
};
};
product.js
'use strict';
const {
Model
} = require('sequelize');
module.exports = (sequelize, DataTypes) => {
class products extends Model {
/**
* Helper method for defining associations.
* This method is not a part of Sequelize lifecycle.
* The `models/index` file will call this method automatically.
*/
static associate(models) {
// define association here
}
};
products.init({
product_name: DataTypes.STRING,
price: DataTypes.NUMBER,
product_description: DataTypes.STRING
}, {
sequelize,
modelName: 'products',
});
return products;
};
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;
Also i have migration's and config's files.
What I must to do to issue this errors or another problems?
Move productModels.js to 'repository' directory
because, there is no 'default' export in this file
And, db operation file cannot sit in models folder
I fixed that, and upload to git https://github.com/nkhs/node-sq-stack.git

Cannot read property 'count' of undefined Express API

When i call Create Option api it is working fine but when i call list api get error: Cannot read property 'count' of undefined Express (Node + MongoDB) API.here is my Option Controller File code.
i have Log DB.ProductDoption ,getting result but count function not working.
const _ = require('lodash');
const Joi = require('joi');
exports.create = async (req, res, next) => {
try {
const validateSchema = Joi.object().keys({
name: Joi.string().required(),
key: Joi.string().required(),
description: Joi.string().allow(['', null]).optional(),
options: Joi.array().items(Joi.object().keys({
key: Joi.string().required(),
displayText: Joi.string().required()
})).required()
});
const validate = Joi.validate(req.body, validateSchema);
if (validate.error) {
return next(PopulateResponse.validationError(validate.error));
}
const key = Helper.String.createAlias(req.body.key);
console.log(DB.ProductDoption);
const count = await DB.ProductDoption.count({ key });
if (count || validate.value.key === '_custom') {
return next(PopulateResponse.error({
message: 'Please add unique name for key'
}));
}
const option = new DB.ProductDoption(validate.value);
await option.save();
res.locals.option = option;
return next();
} catch (e) {
return next(e);
}
};
exports.list = async (req, res, next) => {
const page = Math.max(0, req.query.page - 1) || 0; // using a zero-based page index for use with skip()
const take = parseInt(req.query.take, 10) || 10;
try {
const query = Helper.App.populateDbQuery(req.query, {
text: ['name', 'key', 'description']
});
const sort = Helper.App.populateDBSort(req.query);
const count = await DB.ProductDoption.count(query);
const items = await DB.ProductDoption.find(query)
.collation({ locale: 'en' })
.sort(sort).skip(page * take)
.limit(take)
.exec();
res.locals.optionList = {
count,
items
};
next();
} catch (e) {
next(e);
}
};
collection.count is deprecated, and will be removed in a future version. Use Collection.countDocuments or Collection.estimatedDocumentCount instead

Categories

Resources