cannot read property query of undefined - node.js

ErrorMy file database/index.js
I´m trying execute a query on my heroku database, but any request to the database causes this error.
const {Pool} = require('pg');
const pool =
new Pool({connectionString : Process.env.DATABASE_URL, ssl : true});
module.exports = {
query : function(text, values, ret_cb, err_cb){
pool.connect(function(err, client, done){
client.query(text, values).then(ret_cb).catch(err_cb);
});
}
};

Check the err value in your callback from pool.connect(...), you're probably getting a connection error.
The simplest debugging is to log out the values of err and client:
pool.connect(function(err, client, done){
console.log('err=', err);
console.log('client=', client);
client.query(text, values).then(ret_cb).catch(err_cb);
});
For interactive debugging it might be work looking at Debugging Node.js with Chrome DevTools.

Related

Disconnect PostgreSQL when client goes to new page

I'm trying to build a real time web page and use postgreSQL as my database. I use node.js and express to build backend stuff. Since this is a real time webpage and needs to update information very frequently, I keep a long connection with postgreSQL, which looks like:
app.get('/:A/:B', function(req,res){
var A = req.params.A;
var B = req.params.B;
var client = new pg.Client(config[A][B]);
client.connect(function(err){
if (err) {
console.log("Error occurred when try to connect the database",err);
}
else {
console.log("Connected to the database");
}
});
Do some queries with current database connection...
}
The problem is, when I change the value of A and B in browser and try to connect to a new database, I didn't disconnect with the old one so the info on my page are still from the old database. I'm new to node and web development. Can anyone let me know how to disconnect with the old database when client try to go to a new url?
I think is not good way to create connection for each request. If size of A-B variants is limited then create of connection pool on start is better.
app.get('/:A/:B', function(req, res, next){ // next to forwarding error
var A = req.params.A;
var B = req.params.B;
var client = new pg.Client(config[A][B]);
client.connect(function(err){
if (err)
return next(err); // go to error-middleware
console.log("Connected to the database");
// Do some queries with current database connection...
// Keep it mind that they're also asynchronous, so better way is use promises or async (https://github.com/caolan/async)
client.end(function (err) {
if (err)
next(err);
});
});
}
// Error middleware
app.use(function(err, req, res, next) {
console.log(req.url, err.message);
})

How do I ignore redis if it is not available?

I want my application (lets say a simple node file for now) to work as it is even if redis is not available. I'm not able to do it the correct way. This is what I've tried.
var redis = require('redis');
var redisClient = null;
var getRedisClient = function(){
if(redisClient){
return redisClient;
}
try {
redisClient = redis.createClient({connect_timeout : 5000, max_attempts : 1});
redisClient.on("error", function(err) {
console.error("Error connecting to redis", err);
redisClient = null;
});
return redisClient;
} catch(ex){
console.log("error initialising redis client " + ex);
return null;
}
};
try {
var client = getRedisClient();
console.log("done!");
} catch (ex){
console.log("Exception");
}
However, with this code my application exits if redis is not available (it shouldn't because i've not given a process.exit() command).
How can I solve this?
Checking for Successful Connection on Start
Using a promise, you could guarantee that at least initially, you were able to connect to redis without error within a specified time period:
const redis = require('redis');
const Promise = require('bluebird');
function getRedisClient(timeoutMs){
return new Promise((resolve, reject) => {
const redisClient = redis.createClient();
const timer = setTimeout(() => reject('timeout'), timeoutMs);
redisClient.on("ready", () => {
clearTimeout(timer);
resolve(redisClient);
});
redisClient.on("error", (err) => {
clearTimeout(timer);
reject(err);
});
});
};
const redisReadyTimeoutMs = 10000;
getRedisClient(redisReadyTimeoutMs)
.then(redisClient => {
// the client has connected to redis sucessfully
return doSomethingUseful();
}, error => {
console.log("Unable to connect to redis", error);
});
You Need Proper Error Handling
The redis client being non-null does NOT guarantee using it won't throw an error.
you could experience infrastructure misfortune e.g. crashed redis process, out of memory or network being down.
a bug in your code could cause an error e.g. invalid or missing arguments to a redis command.
You should be handling redis client errors as a matter of course.
DON'T null the Redis Client on Error
It won't give you much but it will force you to check for null every time you try and use it.
The redis client also has inbuilt reconnect and retry mechanisms that you'll miss out on if you null it after the first error. See the redis package docs, look for retry_strategy.
DO Wrap your redis client code with try .. catch ... or use .catch in your promise chain.
DO Make use of a retry_strategy.

Problems Deploying a Node.js app on Heroku Using MongoLab

I'm attempting to deploy a very simple app to Heroku. The code for the application can be found on Ray Wenderlich's site, here: http://www.raywenderlich.com/61078/write-simple-node-jsmongodb-web-service-ios-app I keep getting the same error whenever I try to have Heroku compile the code...
var mongoHost = "mongodb://username:password#ds041140.mongolab.com:41140/heroku_app23491233";
var mongoPort = 41140;
var collectionDriver;
var mongoClient = new MongoClient(new Server(mongoHost, mongoPort)); //B
mongoClient.open(function(err, mongoClient) { //C
if (!mongoClient) {
console.error("Error! Exiting... Must start MongoDB first");
process.exit(1); //D
}
var db = mongoClient.db("heroku_app23491233"); // E
collectionDriver = new CollectionDriver(db); //F
});
When I type heroku logs, the error I get comes from if (!mongoClient) above...
app[web.1]: Error! Exiting... Must start MongoDB first
I'm sure the problem lies somewhere in my attempt to connect to the MongoLab database. I've copied the URI from MongoLab and I've created a user with the proper credentials.
I can connect to localhost just fine with very similar code, so I'm not sure what is going wrong in this example.
Thank you.
Based on the docs, my best guess is that it's because the Server constructor expects the first argument to contain only the host name (in the case of your MongoLab, ds041140.mongolab.com). However, I think you can pass your connection string into MongoClient.connect:
// Make sure to replace username and password with the proper values.
var mongoHost = "mongodb://username:password#ds041140.mongolab.com:41140/heroku_app23491233";
MongoClient.connect(mongoHost, function(err, db) {
if (err) return console.log(err);
db.collection('mongoclient_test').update({a:1}, {b:1}, {upsert:true}, function(err, result) {
db.close();
if (err) return console.log(err);
console.log('Okay', result);
});
});
Documentation Page For MongoClient
Hopefully that helps!

Express keeping connection open?

I'm using node js, express and postgresql as backend.
This is the approach I used to make a rest API:
exports.schema = function (inputs, res) {
var query = knex('schema')
.orderBy('sch_title', 'asc')
.select();
query.exec(function (err, schemas) {
if(err){
var response = {
message: 'Something went wrong when trying to fetch schemas',
thrownErr: err
};
console.error(response);
res.send(500, response);
}
if(schemas.length === 0){
var message = 'No schemas was found';
console.error(message);
res.send(400, message);
return;
}
res.send(200, schemas);
});
};
It works but after a while postgres logs an error and it's no longer working:
sorry, too man clients already
Do I need a close each request somehow? Could not find any about this in the express docs. What can be wrong?
This error only occurs on production server. Not on developing machine.
Update
The app only brakes in one 'module'. The rest of the app works fine. So it's only some queries that gives the error.
Just keep one connection open for your whole app. The docs shows an example how to do this.
This code goes in your app.js...
var Knex = require('knex');
Knex.knex = Knex.initialize({
client: 'pg',
connection: {
// your connection config
}
});
And when you want to query in your controllers/middlewares...
var knex = require('knex').knex;
exports.schema = function (req, res) {
var query = knex('schema')
.orderBy('sch_title', 'asc')
.select();
// more code...
};
If you place Knex.initialize inside an app.use or app.VERB, it gets called repeatedly for each request thus you'll end up connecting to PG multiple times.
For most cases, you don't need to do an open+query+close for every HTTP request.

Connecting to mongodb

Code:
var Db = require('mongodb').Db,
Server = require('mongodb').Server,
Client = new Db('test', new Server('127.0.0.1', 52235, {}))
In Function:
...
Client.open(function(err, pClient) {
Client.collection('test_insert', function(err, collection){
collection.find().toArray(function(err, results) {
console.log(results);
});
});
// etc.
});
This shows error: Cannot read property 'arbiterOnly' of undefined
can you help me?
This error occurs because it couldn't connect to the server and so the configuration information wasn't properly received. Probably you are using the wrong port: try 27017.

Resources