i am trying to connect mysql, but it is showing me req.getConnection is not a function
Bellow is the code snipet which i have used.
In app.js
var mysql = require('mysql'),
connection = require('express-myconnection'),
dbOptions = {
host: 'localhost',
user: 'root', password: '',
port: 3306,
database: 'nodejs'
};
app.use(connection(mysql, dbOptions, 'request'));
In Customers.js
exports.list = function(req, res, next) {
req.getConnection(function(err, connection) {
if (err) return next(err);
connection.query('SELECT * FROM customer', function(err, rows) {
if (err) console.log("Error Selecting : %s ", err);
res.render('customers', {
page_title: "Customers - Node.js", data: rows
});
});
});
};
Can you please check what is have done wrong. I am pretty new in nodejs, so may be i am missing something.
If you want to check my complete package, please follow bellow URL, i have push all code in my git repository
https://github.com/chiraggmodi/nodeCrud
You need to move this line:
app.use(connection(mysql, dbOptions, 'request'));
Right now, it's declared after your routes, which means that requests will never pass through it (that's how Express works: requests are passed through both middleware and route handlers in order of their declaration).
If you use it to a location in the code before the routes that require req.getConnection() to work (perhaps here), requests will first pass through the express-myconnection middleware and then get passed to the route handlers, making sure that req.getConnection() will be available inside those route handlers.
EDIT: on closer look, your customer routes are also incorrect.
You have this:
router.get('/', function(req, res, next) {
res.render('customers', customers.list);
});
But customer.list is a route handler in itself, not something you should pass to res.render(). Instead, try this:
router.get('/', customers.list);
(and similarly for all the other routes in customers_route.js)
Related
I'm new to javascript and node.js.
Can someone answer the following questions.
1. How I split the PostgreSQL part properly in an other file.
2. How I the pest practice is to use the pg pools.
3. How I improve this code for production.
const express = require('express');
const app = express();
const pg = require('pg');
const pool = new pg.Pool({
user: 'admin',
password: 'test123!',
host: '127.0.0.1',
port: '5432',
database: 'test_db'
});
app.get('/api/recipes', function(req, res){
pool.connect(function(err, client, done) {
if(err){
console.log('Connection failed '+ err);
res.status(400).send(err);
}
client.query('SELECT * FROM recipes;', function(err, result) {
done();
if(err){
console.log('Error with query! ERROR code: ' + err.code);
res.status(400).send(err);
}
else{
res.status(200).send(result.rows)
}
});
});
});
app.get('/api/recipes/:id', function(req, res){
var id = req.params.id;
pool.connect(function(err, client, done) {
if(err){
console.log('Connection failed ' + err);
res.status(400).send(err);
}
else{
client.query('SELECT * FROM recipes WHERE recipes_id = $1;', [id], function(err, result) {
done();
if(err){
console.log('Error with query! ERROR code: ' + err.code);
res.status(400).send(err);
}
else{
res.status(200).send(result.rows)
}
});
}
});
});
app.listen(3000,function(){
console.log('Server listen on port 3000');
});
There are a lot of ways folks go to split the code you've described. I'll take it piece by piece.
First, pull any configurable variables out and setup one file that can get them from the environment (possibly with dev defaults in place, your choice on that). You can use a library like commander or convict, but honestly I prefer to just write a simple file that pulls them myself:
// ./config.js
module.exports = {
pool: {
user: process.env.DB_USER || 'admin',
password: process.env.DB_PW || 'test123!',
host: process.env.DB_HOST || '127.0.0.1',
port: process.env.DB_PORT || '5432',
database: process.env.DB_NAME || 'test_db'
}
};
As for your database calls, some folks like to use ORM-like stuff such as sequelize, but again I tend to start simple and add things as needed. In your case, you should think about what boilerplate stuff you can make common code around, and then wrap those into simple modules that only expose to the calling code stuff it really needs. For example, you will note that most of your routes are going to connect to the pool, test for an error, then run a query if it doesn't error out, and finally render either the error or query results, right? So that can all be wrapped into a fairly simple query function that handles the boilerplate internally and works with just a query expression and a callback, for example:
// ./db/index.js
const pg = require('pg');
const config = require('./config');
const pool = new pg.Pool(config.pool);
function query(sql, params, callback) {
// maybe check for valid inputs here or something, but at least normalize in case folks don't pass params
if(arguments.length < 3) {
callback = params;
params = null;
}
pool.connect((err, client, done) => {
// just exit here and let the calling code know there was a problem
if(err) return callback(err);
// I haven't tested this w/ the pg library recently, you might have to do two of these if it doesn't like null as a second argument
client.query(sql, params, (err, result) => {
if(err) return callback(err);
done();
// calling code probably doesn't care about anything but rows, but you can do other stuff here if you prefer
return callback(null, result.rows);
});
});
};
// You can also add additional functions if you want shorthand for doing things like query by ID or with params, or similar
module.exports = { query };
I also think that it can be helpful to store the SQL strings somewhere centrally, or on model objects, just to make the routing code note have to care about that. For a super simple example using your two routes, I might do something like this:
// ./db/queries.js
module.exports = {
RECIPES: {
LIST: 'SELECT * FROM recipes;',
FIND_BY_ID: 'SELECT * FROM recipes WHERE recipes_id = $1;'
}
};
Ok, so now your routing code can be quite simple, you can just get the db module and work the query, letting the routing worry just about what it's got to do with the request and response. Another option that folks like is to actually create a module for each model in your app (e.g. a Recipe) that wraps the above two files into a set of static functions so that your routes don't even know they're querying specifically. The calls in that case would be something like Recipe.list(cb) or Recipe.findById(id, cb). This is a style made popular by Ruby on Rails a few years ago, it has mixed acceptance in the Node community, but I'm mentioning it for completeness.
// ./routes/recipes.js
const router = require('express').Router();
const db = require('./db');
const queries = require('./db/queries');
router.get('/api/recipes', (req, res, next) => {
db.query(queries.RECIPES.LIST, (err, rows) => {
if(err) return next(err);
return res.send(rows); // status 200 is the default here
});
});
router.get('/api/recipes/:id', (req, res, next) => {
const id = req.params.id;
db.query(queries.RECIPES.FIND_BY_ID, [id], (err, rows) => {
if (err) return next(err);
return res.send(rows);
});
});
Finally, in your main Express setup file:
// ./app.js
const express = require('express');
const app = express();
const recipeRoutes = require('./routes/recipes') // note if you have an index.js file that gets imported just by calling for the folder, so that's a way to group features as well
app.use(recipeRoutes);
// I'm a big fan of error handling middleware. There's a more complex approach I did in [praeter][4] that gives you http-verb based errors that you can then catch and send the appropriate status, but that's again more complex than you might need here.
app.use((err, req, res, next) => {
// this can be as simple or as complex as you like.
// note it's a best practice to send only "clean" messages to the client, so you don't give away that you're using a Postgres db or other stuff that makes hacking easier.
console.error(err);
res.status(500).send('Oops! Something went wrong!!');
});
Obviously, there's a lot of ways to skin this cat, so I'd recommend mostly just looking for where you're repeating yourself, and then refactor to repeat less. Also, if you're interested in making more production-ready apps in general, the 12 factor app is a must-read.
To answer number 1,
dbPool.js
const pg = require('pg');
export.pool = new pg.Pool({
user: 'admin',
password: 'test123!',
host: '127.0.0.1',
port: '5432',
database: 'test_db'
});
app.js
const express = require('express');
const app = express();
const pool = require('./dbPool');
....
You should create config file and require that file in app.js
--config
----config.js
--app.js
var config = {
production: {
pool: {
user: 'admin',
password: 'test123!',
host: '127.0.0.1',
port: '5432',
database: 'test_db'
}
},
development: {
pool: {
user: 'admin',
password: 'test123!',
host: '127.0.0.1',
port: '5432',
database: 'test_db'
}
}
}
exports.get = function get(env) {
return config[env] || config.development;
}
As stated, multiple callback functions can be provided and behave like middleware to handle a request. They can be in the form of a function, an array of functions, or combinations of both, as shown in the following examples.
For example:
app.get('/example/b', function (req, res, next) {
console.log('the response will be sent by the next function ...')
next()
}, function (req, res) {
res.send('Hello from B!')
})
What's the purpose of this? Can't we simply use:
app.get('/example/b', function (req, res) {
console.log('the response will be sent by the next function ...')
res.send('Hello from B!')
})
The multiple functions would more likely be used when you already have a previously defined function that you probably intend to use in multiple places. For example:
app.get("/somePath", checkAuth, function(req, res) {
// you know it's already authenticated here
});
app.get("/someOtherPath", checkAuth, function(req, res) {
// you know it's already authenticated here
});
function checkAuth(req, res, next) {
if (some logic here) {
// allow handler chain to continue
next();
} else {
// auth error
res.status(401).end();
}
}
Of course, you could also use middleware for checking authentication, but the above example allows you to target just a few specific routes with some middleware that you may use in multiple places.
As you have already observed, if you don't intend to use the function anywhere else, then you may as well just put the logic into your one handler.
Yes you can, the purpose is for example, to handle errors, the middleware sequence in express allows you to use this way. For example, see this way to set up the express config:
app.use(logger.connectLogger());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: false
}));
app.use(routes);
app.use(errorConnect);
http.createServer(app).listen(config.port, function () {
logger.getLogger().info('My backend listening on port: ' + config.port);
});
My routes module have all the matching route -> callback:
// Methods exposed for backend API.
router.get('/status', ips.getStatus);
router.route('/ip')
.post(ips.keepIps)
.get(ips.getIps)
// NOT ALLOWED
.put(returnNotAllowed)
.delete(returnNotAllowed);
// Methods exposed and used by IP's frontend.
router.route('/front/ip')
.get(front.getIpsByFront)
.post(front.keepIpsByFront);
router.post('/login', login.login);
....
For example in one of those callbacks, I have the next way to manage an incoming request:
/**
* Login user from frontend.
*/
exports.login = function(req, res, next) {
var username = req.body.username + '#System',
password = req.body.password,
server = req.body.server,
auth = 'Basic ' + new Buffer(username + ':' + password).toString('base64');
loginApi.login(auth, server)
.then(function(result) {
res.statusCode = 200;
res.send(result);
})
.catch(function(error) {
next({
statusCode: 403,
message: 'Error in login'
});
});
};
When I catch an error, I call next with a custom error object, and after this, if you back and watch the config (first paragraph) you can see that I added to the express middleware an error manage with errorConnect. In my opinion this is a usefull way to understand what you are asking because if I understand well you had doubts with next()
Using ReactJS, Redux, Webpack, Node.js and Express with MongoDB, I am following the tutorial https://github.com/vasansr/mern-es6 and trying to integrate it into my project. First, I am trying to make a POST request to the server I created. And it gets a response with a success and no error is logged. Yet inside the server POST API, it does not log console.log('Req body', req.body);, and in terminal I checked to see if the database has been created with mongo -> show dbs but it is empty.
Could it be that something is intercepting the request from the server? What could be the issue?
This...
app.use('/', function (req, res) {
res.sendFile(path.resolve('client/index.html'));
});
comes before:
app.post('/api/users/', function(req, res) {
//...
});
Since it's app.use the POST /api/users will still hit that middleware, and res.sendFile ends the request/response. You'll probably see that your post is getting back the client HTML.
Try moving your client HTML endpoint to the end of your middleware, just before the error handlers if you have them. That way, it'll only get used if none of your API endpoints match. Or if you want just GET / to return the HTML, change use to get:
app.use(webpackDevMiddleware(compiler, {noInfo: true, publicPath: config.output.publicPath}));
app.use(webpackHotMiddleware(compiler));
app.use(express.static('dist')); //where bundle.js is
app.use(bodyParser.json());
app.post('/api/users/', function(req, res) {
console.log('Req body', req.body);
var newUser = req.body;
db.collection('users').insertOne(newUser, function(err, result) {
if(err) console.log(err);
var newId = result.insertedId;
db.collection('users').find({_id: newId}).next(function(err, doc) {
if(err) console.log(err);
res.json(doc);
});
});
});
app.get('/', function (req, res) {
res.sendFile(path.resolve('client/index.html'));
});
app.post('/api/users/', function(req, res) {
console.log('Req body', req.body);
var newUser = req.body;
db.collection('users').insertOne(newUser, function(err, result) {
if(err) console.log(err);
var newId = result.insertedId;
db.collection('users').find({_id: newId}).next(function(err, doc) {
if(err) console.log(err);
res.json(doc);
});
});
});
I have a small comments about this code, for if(err) console.log(err); i think you should change to if(err) return console.log(err);.
For error case, i think you need return, otherwise the below part will be excuted, and there will report some error.
I've made an api and I've routed it as follows:
In the main routes file:
//with sub-route
app.use('/api/test/:test', require('./api/test'));
//Without sub-route
app.use('/api/test2/:test', function(req, res){
console.log('in test', req.params, req.body);
return res.status(200).json({params: req.params, body: req.body});
});
Accessing the second route displays the :test in req.params, as expected.
In the modular routes folder ('./api/test') I have a sub-router (index.js) which looks like this:
router.get('/:test2', controller.getItem);
with a handler:
exports.getItem = function getItem(req, res) {
console.log('in getItem \nreq.params', req.params, '\nreq.body: ', req.body);
return res.status(200).json({yes: 'yes', params: req.params, body: req.body});
};
So the first url, which has no sub-routing is: /api/test2/:test and logs out whatever you put in place of :test in req.params.
The second url, which has sub-routing is: /api/test/:test/:test2, but when you send your get request only :test2 appears in req.params.
It seems that if you use this pattern any variables in the 'root' of the route (ie in the primary router) are not picked up.
Is there a way to fix this?
Thanks
You will need a middleware to fix this for you:
function paramFix(req, res, next) {
req._params = req.params;
next();
}
app.use('/api/test/:test', paramFix, require('./api/test'));
And then use req._params.test in your last callback function.
So reflect multiple levels of mounting you can extend your middleware like this:
function paramFix(req, res, next) {
req._params = req._params || {};
for (var key in req.params) {
if (req.params.hasOwnProperty(key)) {
req._params[key] = req.params[key];
}
}
next();
}
app.use('/api/test/:test', paramFix, require('./api/test'));
express.js (>= v4.5.0+) provides a direct solution without having to implement middleware.
https://expressjs.com/en/api.html#express.router
While creating the router, pass the mergeParams flag.
var router = express.Router({ mergeParams: true })
mergeParams preserves the req.params values from the parent router. If the parent and the child have conflicting param names, the child’s value takes precedence.
I found Difference between put and patch. I kind of understand teh difference after reading. It's still hazy.
My question is:
Why does Yeoman generator: angular fullstack use
router.put('/:id', controller.update);
AND
router.patch('/:id', controller.update);
In there index.js files of their server.collections?
What's the purpose of having both? Moreover, How would I use one vs the other?
'use strict';
var express = require('express');
var controller = require('./thing.controller');
var router = express.Router();
router.get('/', controller.index);
router.get('/:id', controller.show);
router.post('/', controller.create);
router.put('/:id', controller.update);
router.patch('/:id', controller.update);
router.delete('/:id', controller.destroy);
module.exports = router;
server controller
// Updates an existing thing in the DB.
exports.update = function(req, res) {
if(req.body._id) { delete req.body._id; }
Thing.findById(req.params.id, function (err, thing) {
if (err) { return handleError(res, err); }
if(!thing) { return res.send(404); }
var updated = _.merge(thing, req.body);
updated.save(function (err) {
if (err) { return handleError(res, err); }
return res.json(200, thing);
});
});
};
They are just different http verbs. Reading https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods
PUT
Requests that the enclosed entity be stored under the supplied URI. If the URI refers
to an already existing resource, it is modified; if the URI does not point to an existing
resource, then the server can create the resource with that URI.[15]
PATCH
Applies partial modifications to a resource.[18]
They should'n be the same!
But I see no difference on both methods on angular-fullstack and for me it is wrong!
PUT - update the entire entity, this means you need to send EVERY
single property of the item otherwise they will be erased.
PATCH - partial update, you may send only the fields you want to
change and the others will be kept on the server.
e.g:
Imagine the following entity:
car: {
color: red,
year: 2000
}
Now imagine you send a patch like this:
{color: blue}
The entity is now like this:
car: {
color: blue, // CHANGED
year: 2000
}
But instead if you sent a put the entity should like this:
car: {
color: blue // CHANGED
year: null // May be null, undefined, removed, etc...
}