Cannot read property 'findAll' of undefined sequelize - mysql

I'm a new learner to express js and sequelizejs. I successfully migrate table in my database so the connection is fine I guess.
Here is my code.
https://github.com/Picks42/express-test
Please review this file
https://github.com/Picks42/express-test/blob/master/models/user.js
Then review this one
https://github.com/Picks42/express-test/blob/master/controller/test.js
Let me know what's the issue.

// all the models using your index.js loader
const models = require('../models');
// the user model, note the capital User since
const M_Bank = models.User;
exports.getTest = function(req,res){
return M_Bank
.findAll()
// don't use M_Bank here since you are getting an array of Instances of the Model
.then(users => res.status(200).send(users))
.catch((error) => {
console.log(error.toString());
res.status(400).send(error)
});
/* this will never execute because it is after the return
exports.index = function (request, response, next) {
response.json((M_Bank.findAll()));
};
*/
};
If you have the option of using async/await it makes for more readable code.
const models = require('../models');
const M_Bank = models.User;
exports.getTest = async function(req, res) {
try {
const users = await M_Bank.findAll();
return res.status(200).send(users);
} catch (err) {
console.log(err.toString());
return res.status(400).send(err);
}
};

You should get rid of the .User field in the 3rd line. because you've exported User itself from the models/user file.
Also, I recommend you not to mess with variables names. M_Bank variable doesn't speak itself
const M_Bank = require('../models/user');
exports.getTest = function(req,res){
return M_Bank
.findAll()
.then(M_Bank => res.status(200).send(M_Bank))
.catch((error) => {
console.log(error.toString());
res.status(400).send(error)
});
exports.index = function (request, response, next) {
response.json((M_Bank.findAll()));
};
};

Related

How to convert MySql Buffer to Image in React/Node/Express

I need help to convert a buffer to a base64 using Node and React.
I'm posting an image with an input to my databse and I'm not sure I'm doing it right. This is my first time doing this. Is there something missing here? Back-end POST request:
app.post("/api/img", (req, res) => {
const productimg = req.body.productimg;
const sqlInsert = "INSERT INTO users_files (file_src) VALUES (?)";
db.query(sqlInsert, [productimg], (err, result) => {
console.log(result);
})
})
In the database the image is a blob, and then with the GET request I get the image as a buffer. This is the GET request in the front-end:
useEffect(() => {
Axios.get('http://localhost:3001/api/get/img').then((base64String) => {
setBackenddata(base64String.data)
var blob = new Blob(productImg[0]?.file_src, {
type: "image/jpg",
});
var reader = new FileReader();
reader.readAsDataURL(blob);
reader.onloadend = function () {
let base64String = reader.result;
setProductImg(base64String);
};
console.log(base64String)
})
}, [])
And this is the get function in the back-end:
app.get('/api/get/img', (req, res) => {
const sqlGet = "SELECT * FROM users_files";
db.query(sqlGet, (err, result) => {
res.send(result);
})
})
This is what I get from the base64String:
The base64String does not seem to do anything, since it is still type: buffer.
In the back end I have tried with a Multer, but that did not work. I've been trying with different things in the back-end and the front-end, but since I'm new to this it is hard to know what's wrong.

Add transaction to sequelize create module

I'm starting with sequelize to create an API and I'm facing an issue with transactions.
My sequelize database configuration looks like this:
var Sequelize = require('sequelize');
var sequelize = new Sequelize(CONFIG.database, env.user,
env.password, {
host: env.host,
dialect: env.dialect,
port: env.port,
operatorsAliases: false
});
var db = {};
fs.readdirSync(__dirname).filter(function (file) {
return (file.indexOf('.') !== 0) && (file !== 'index.js');
}).forEach(function (file) {
var model = sequelize.import(path.join(__dirname, file));
db[model.name] = model;
});
Object.keys(db).forEach(function (modelName) {
if ('associate' in db[modelName]) {
db[modelName].associate(db);
}
});
db.sequelize = sequelize;
db.Sequelize = Sequelize;
module.exports = db;
Then I have a stockcontroller with functions to save in database like this:
var exports = module.exports = {}
let Stock = require('../models').Stock;
let StockVariant = require('../models').StockVariant;
exports.create = function (req, res) {
const body = req.body;
console.log(body);
Stock.create(body).then(function (stock, created) {})...}
I want to create transaction to save into stockvariant and stock tables in one single transaction and have the option to rollback when error.
Documentation in sequelize doesn't look easy for me to understand as I don't see how to apply this
return sequelize.transaction(function (t) { return User.create({}) })
because t is of course not defined anywhere and my stockcontroller doesn't import sequelize.
So in the end I don't understand the basic concept of how to define that transaction function to create a new stock line.
Thanks for your help!
The sequelize instance needs to be imported to use transactions. It is already exported in your database configuration file with this line db.sequelize = sequelize.
All you need to do is adding it in the current imports :
var exports = module.exports = {}
const Stock = require('../models').Stock; // Prefer const usage to avoid overwritting imports
const StockVariant = require('../models').StockVariant;
const sequelize = require('../models').sequelize;
This could also be done in one line using destructuring :
const { Stock, StockVariant, sequelize } = require('../models');
Now let's come to the transaction. As stated in the documentation, you have two ways of handling them : managed or unmanaged.
Managed transaction
This is done by chaining your asynchronous operations inside the sequelize transaction callback. In this case, if the operations linked to the transaction succeed, the transaction will commit automatically, otherwise it will rollback.
exports.create = function (req, res) {
const body = req.body;
console.log(body);
sequelize.transaction(function(t) {
return Stock.create(body, {transaction: t}) // We pass the transaction as a parameter here !
.then(function(stock, created) {
return StockVariant.create(..., {transaction: t}) // The transaction, again here
})
.catch(function(err) {
// Handle your error...
});
}
Unmanaged transaction
If you want more transparency and/or control over your transaction, you can use an unmanaged transaction. In this case, you must call commit and rollback manually.
exports.create = function (req, res) {
const body = req.body;
console.log(body);
sequelize.transaction
.then(function(t) { // Note the 'then' usage here
return Stock.create(body, {transaction: t}); // We pass the transaction as a parameter here !
.then(function(stock, created) {
return StockVariant.create(..., {transaction: t}); // The transaction, again here
});
.then(function() {
return t.commit();
})
.catch(function(err) {
return t.rollback();
});
}
This could also be done with async / await syntax, which may be more pleasant to read :
exports.create = function (req, res) {
const body = req.body;
console.log(body);
let t; // The variable in which the transaction object will be stored
try {
t = await sequelize.transaction();
const stock = await Stock.create(body, {transaction: t})
await StockVariant.create(..., {transaction: t}) // Whatever parameter you need to pass here
await t.commit();
} catch (err) {
await t.rollback();
}
}

can´t make your two or more methods in same route

the link to the project
https://github.com/Kammikazy/project
i can´t make work my get two or more methods in same route
i have the code 404
i using mysql nodejs and express
my code
controller alliances
const User = require('../models/Alliances')
const findAlianca = async (connection, req, res) => {
const Allianca = await User.find(connection, req.session.user.username)
if (!Allianca) {
res.status(404).send('Nenhuma cidade encontrada.');
return;
}
console.log("dddd");
req.session.Allianca = Allianca
res.locals.Allianca = Allianca
res.render('Administration/Alliances')
}
module.exports = {
findAlianca
}
route aliance
const express = require('express')
const router = express.Router()
const connection = require('../../Config/database')
const controllerAdmin = require('../../controllers/Administration')
const controlleruser = require('../../controllers/Alliances')
router.get('/Administration/Alliances', (req, res) => controllerAdmin.findcidade3(connection, req, res))
router.get('/Administration/Alliances/limitado', (req, res) => controlleruser.findAlianca(connection, req, res))
module.exports = app => app.use('/', router)
models aliance
const find = (connection,username) => {
return new Promise((resolve, reject) => {
connection.query(SELECT alianca.nome,alianca.N_membros,alianca.TAG FROM user INNER JOIN alianca ON user.cod_alianca=alianca.id WHERE user.username='${username}', (err, result) => {
if(err){
reject(err)
}else{
resolve(result)
}
})
})
}
module.exports = {
find
}
alliance.jade
extends layout
block title
.col-xs-6.col-xs-offset-3.col-sm-6.col-sm-offset-3
.col-sm-4(style='width:76%')
div.panel.panel-primary(style='height:50px') Alliances Page
div.panel.panel-primary(style='height:700px') fdssdklfsdklfjskldfjkldsjfl
if locals.user.cod_alianca==null
p You Dont Have Alliances
else
br
span Your Aliance
span= locals.Allianca.nome
.col-xs-2.panel-red(style='width:24%;height:100%;text-align:center')
my app
require('./routes/Administration/Alliances')(app)
my connection db
const mysql = require('mysql')
const config = require( "./config.json" )
const connection =mysql.createConnection({
host:config.host,
user:config.user,
password:config.password,
database:config.database,
// port:config.port
});
connection.connect((err) =>{
if(err){
console.log(err)
process.exit(0)
}else{
console.log('database on')
}
})
what i doing wrong i can´t find the solution for my problem
Not sure what you are asking however if you want to call multiple function in same route/API you can do following:
Using expressJs you can use next function like:
app.get('/Administration/Alliances', (req, res, next) => {
//Do something here and to add data to your request use
req.body.newData = 'newData';
//after this just call next function
next();
}, (req, res, next) => {
//Can continue this cycle of calling next function until last `sendResponse` function is reached.
//Can even set `error` in request for `sendResponse`
req.error = "Some error";
next();
}, (req, res) => {
if(req.error) {
res.status(400).send(req.error);
} else {
res.status(200).send(req.body.result);
}
});
the soluction for my problem
const express = require('express')
const router = express.Router()
const connection = require('../../Config/database')
const controllerAdmin = require('../../controllers/Administration')
const controlleruser = require('../../controllers/Alliances')
router.get('/Administration/Alliances', (req, res, next) => {
//Do something here and to add data to your request use
controllerAdmin.findcidade3(connection, req, res)
next();
}, (req, res, next) => {
//Can continue this cycle of calling next function until last `sendResponse` function is reached.
//Can even set `error` in request for `sendResponse`
controlleruser.findAlianca(connection, req, res)
})
module.exports = app => app.use('/', router)

var is undefined if using var keyword node

Building a small MVC. When I'm receiving results back from my model, the variable that I'm using to send to my view is undefined if I use the "var" keyword. If I don't use the keyword the object comes through just fine. What is happening?
Controller
const homeModel = require('../models/homeModel.js');
exports.index = function(req, res){
homeModel.getAllStores(function (err, res) {
if (err) return err;
stores = res; // Works
var stores = res // Undefined
})
console.log(stores);
res.render('home', {stores: stores});
}
Here is the Model
const db = require('../db.js');
exports.getAllStores = function(done) {
db.query('select * from stores;', (err, rows) => {
if (err) return done(err);
let resultJson = JSON.stringify(rows);
resultJson = JSON.parse(resultJson);
return done(null, resultJson);
})
}
You need to move the declaration of stores to the function enclosing homeModel.getAllStores(). This is because JavaScript is function (lexically) scoped, so a variable will be scoped to the nearest enclosing function. You can read more about how variables that are declared using var work on MDN.
In Node.js, if you don't provide the var keyword before your variable then it is globally scoped to the module in which it is running, this is why console.log(stores) works when you use stores = res and not var stores = res.
To properly scope your variable using var, just move your declaration to the function being exported.
Additionally, your console.log() and res.render() calls are occurring before the callback function for homeModel.getAllStores() is executed and setting stores = res. Since res.render() and console.log() will only work as expected within the callback to homeModel.getAllStores() you can simplify index() and the callback to homeModel.getAllStores().
const homeModel = require('../models/homeModel.js')
exports.index = (req, res) => {
return homeModel.getAllStores((err, stores) => {
if (err) {
throw err
}
console.log(stores)
return res.render('home', {stores})
})
}
You could also use util.promisify() and async/await to write this a little more straightforward.
const {promisify} = require('util')
const getAllStores = promisify(require('../models/homeModel').getAllStores)
const index = async (req, res) => {
let stores
try {
stores = await getAllStores()
} catch (err) {
console.error(err)
return res.sendStatus(500)
}
return res.render('home', {stores})
}
module.exports = {index}
Here is an example with Promise.all() waiting for the results from multiple queries with a hypothetical UserModel with getAllUsers() that works identically to homeModel.getAllStores() but queries a users table.
const {promisify} = require('util')
const getAllUsers = promisify(require('../models/userModel').getAllUsers)
const getAllStores = promisify(require('../models/homeModel').getAllStores)
const index = async (req, res) => {
let queryResults
try {
queryResults = await Promise.all([getAllStores, getAllUsers])
} catch (err) {
console.error(err)
return res.sendStatus(500)
}
let [stores, users] = queryResults
return res.render('home', {stores, users})
}
module.exports = {index}

nodejs - stub module.exports functions with sinon

I have an expressjs app with the following routes and middleware modules. I am trying to test the routes module using mocha, chai, http-chai and sinonjs.
The API uses mysql and in order to test the routes module, I have it all modularized so that I can stub out the mysql module.
However when I try to stub middleware/index, I am having trouble. If I try to require index normally, the module doesn't actually get stubbed. If I try to require it using require.cache[require.resolve('./../../lib/routes/middleware/index')];, it seems to stub something, but indexStub.returns(indexObj) returns an error TypeError: indexStub.returns is not a function and TypeError: indexStub.restore is not a function.
How do I stub out index.js properly in order to control the code flow and keep it from trying to connect to mysql?
routes.js
'use strict';
const express = require('express');
const router = express.Router();
const configs = require('./../config/configs');
const middleware = require('./middleware/index');
const bodyParser = require('body-parser');
const useBodyParserJson = bodyParser.json({
verify: function (req, res, buf, encoding) {
req.rawBody = buf;
}
});
const useBodyParserUrlEncoded = bodyParser.urlencoded({extended: true});
// creates a new post item and return that post in the response
router.post('/posts', useBodyParserUrlEncoded, useBodyParserJson, middleware.validatePostData, middleware.initializeConnection, middleware.saveNewPost, middleware.closeConnection, function(req, res) {
if (res.statusCode === 500) {
return res.send();
}
if (res.statusCode === 405) {
return res.send('Item already exists with slug ' + req.body.slug + '. Invalid method POST');
}
res.json(res.body).end();
});
module.exports = router;
middleware/index.js
'use strict';
const configs = require('./../../config/configs');
const database = require('./../../factories/databases').select(configs.get('STORAGE'));
const dataV = require('./../../modules/utils/data-validator');
module.exports = {
initializeConnection: database.initializeConnection, // start connection with database
closeConnection: database.closeConnection, // close connection with database
saveNewPost: database.saveNewPost, // creates and saves a new post
validatePostData: dataV.validatePostData, // validates user data
};
spec-routes.js
'use strict';
var chai = require('chai');
var chaiHttp = require('chai-http');
var sinonChai = require("sinon-chai");
var expect = chai.expect;
var sinon = require('sinon');
chai.use(sinonChai);
chai.use(chaiHttp);
var app = require('./../../app');
describe('COMPLEX ROUTES WITH MIDDLEWARE', function() {
var indexM = require.cache[require.resolve('./../../lib/routes/middleware/index')];
describe('POST - /posts', function() {
var indexStub,
indexObj;
beforeEach(function() {
indexStub = sinon.stub(indexM);
indexObj = {
'initializeConnection': function(req, res, next) {
return next();
},
'closeConnection': function(req, res, next) {
return next();
},
'validatePostData': function(req, res, next) {
return next();
}
};
});
afterEach(function() {
indexStub.restore();
});
it('should return a 500 response', function(done) {
indexObj.saveNewPost = function(req, res, next) {
res.statusCode = 500;
return next();
};
indexStub.returns(indexObj);
chai.request(app)
.post('/posts')
.send({'title': 'Hello', 'subTitle': 'World', 'slug': 'Example', 'readingTime': '2', 'published': false})
.end(function(err, res) {
expect(res).to.have.status(500);
done();
});
});
});
});
You don't use Sinon at all, as it doesn't deal with module loading at all. I see you have started doing this manually using the internal Node API's, but I suggest you do it the way we advise in the Sinon docs regarding this usecase: juse use proxyquire.
It enables you to substitute require calls to ./middleware/index.js for a mock object of your own liking (possibly made using sinon).
You would use it something like this:
var myIndex = {
initializeConnection: sinon.stub(),
closeConnection: sinon.stub(),
saveNewPost: sinon.stub()
};
var app = proxyquire('./../../app', {'./middleware/index': myIndex});