How to properly query Postgresql database using pg with Node.js? - node.js

I am attempting to query a Postgresql database using Node, Express, and the pg module. I am getting the error "TypeError: Cannot read property 'query' of undefined"
I have looked at the node-postgres module website for the correct syntax as well as various other websites. I know that the syntax used to enable pg changed after pg version 6.3.0.
const express = require("express");
const path = require("path");
const bodyparser = require("body-parser");
const consolidate = require("consolidate");
const dust = require("dustjs-helpers");
const pg = require("pg");
var pool = new pg.Pool();
let app = express();
let connect = "postgres://postgres:secret#localhost:5432/my_database";
app.engine("dust", consolidate.dust);
app.set("view engine", "dust");
app.set("views", __dirname + "/views");
app.use(express.static(path.join(__dirname, "public")));
app.use(bodyparser.json());
app.use(bodyparser.urlencoded({extended: false}));
app.get("/", function(request, response, next) {
pool.connect(function(err, client, done) {
if (err) {
console.log(`Not able to get a connection: ${err}.`);
response.status(400).send(err);
}
client.query("SELECT * FROM recipes", function(err, result) {
done();
});
pool.end();
});
});
app.listen(3000, () => {
console.log("Server running on port: 3000");
});
Going to http://server_ip:3000 should show a webpage instead node crashes with this error:
client.query("SELECT * FROM recipes", function(err, result) {
^
TypeError: Cannot read property 'query' of undefined

You need to pass your connection string to pool when you instantiate it.
var pool = new pg.Pool({
connectionString: 'postgres://postgres:secret#localhost:5432/my_database',
});

Related

Sqlite3 error message is shown on Postgresql application

I am learning to build an app using node express and knexjs to connect to the Postgresql database. When I do a post request, this warning message shows up. The data that I try to post is not in the database. Maybe the app thought I am using sqlite3?
sqlite does not support inserting default values. Set the useNullAsDefault flag to hide this warning. (see docs http://knexjs.org/#Builder-insert).
This is my server.js.
const express = require('express');
const app = express();
const path = require('path');
const knex = require('knex');
const bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
const database = knex({
client: 'pg',
connection: {
host : '127.0.0.1',
user : 'xxxxxxx',
password : 'xxxxxxx',
database : 'xxxxxxxxdb'
}
});
app.use(express.static(__dirname + '/../public/'));
app.get('/add_athlete', function(req, res) {
res.sendFile('add_athlete.html', {root: path.resolve(__dirname + '/../public/templates')});
});
app.post('/add_athlete', function(req, res) {
knex('participants').insert({
participant_number: 1,
email: "test#gmail.com",
first_name: "test",
last_name: "again"
})
.then (function () {
res.json({success: true, message: "ok"})
})
});
app.listen(3000);
console.log('Running at port 3000');
Just to make sure, this question has an answer.
As mentioned in the comments, you probably want to use the created database instance.
So instead of knex('participants').insert... you probably want to use database('participants').insert...

Heroku and PSQL - "Cannot read property 'query' of null"

I'm having a problem when I follow the Heroku tutorial with DB.
First error I got was that pg.connect was invalid from PSQL 7. I tried to change this and using pool instead. However, I can´t make it work and I don´t know why.
Client is 'null' so I get
Listening on 5000 C:\Users\a491601\OneDrive - AF\Privat\SHT\node-js-getting- started\index.js:21
client.query('SELECT * FROM test_table', function(err, result) {
TypeError: Cannot read property 'query' of null
Code:
const cool = require('cool-ascii-faces')
const express = require('express')
const path = require('path')
const PORT = process.env.PORT || 5000
var app = express();
app
.use(express.static(path.join(__dirname, 'public')))
.set('views', path.join(__dirname, 'views'))
.set('view engine', 'ejs')
.get('/', (req, res) => res.render('pages/index'))
.get('/cool', (req, res) => res.send(cool()))
.listen(PORT, () => console.log(`Listening on ${ PORT }`))
app.get('/db', function (request, response) {
var pg = require('pg')
var pool = new pg.Pool(process.env.DATABASE_URL)
pool.connect(function(err, client, done) {
client.query('SELECT * FROM test_table', function(err, result) {
done();
if (err)
{ console.error(err); response.send("Error " + err); }
else
{ response.render('pages/db', {results: result.rows} ); }
});
});
pool.end()
});
Please help me, I've tried different thing for hour now, but I can't get i right.

Node js & mongoDB - TypeError: db.collection is not a function

I am trying to post data from POSTMAN to an external database that I created on mLab but I am getting the error db.collection is not a function.
There is a similar question thread but the answer is incomplete and doesn't save any keys/values I put into postman to mLab. The code that I am trying to make work is from this tutorial: https://medium.freecodecamp.com/building-a-simple-node-js-api-in-under-30-minutes-a07ea9e390d2
My Code:
Server.js
const express = require('express'); // Load routes application
const MongoClient = require('mongodb').MongoClient; //Load database connection application
const db = require('./config/db');
const app = express(); // Assign express app a variable
const port = 8000; //Set local port value for server
const bodyParser = require('body-parser'); // **This has to come BEFORE routes
var assert = require('assert'); // ?
var databaseURL ='mongodb://external:api#ds123312.mlab.com:23312/soundfactory';
app.listen(port, () => {
console.log('')
console.log('We are live on ' + port);
console.log('')
});
MongoClient.connect(databaseURL, function(err, db) {
assert.equal(null, err);
console.log("API has succesfully connected to Sound Facotry mlab external database.");
console.log('')
db.close();
});
app.use(bodyParser.urlencoded({ extended: true }))
require('./app/routes')(app, {}); //Must come AFTER express w/ body parser
db.js
module.exports = {
url : 'mongodb://external:api#ds123312.mlab.com:23312/soundfactory'
};
index.js
const noteroutes = require('./note_routes');
module.exports = function(app,db)
{
noteroutes(app,db);
};
note_routes.js
module.exports = function(app, db) {
app.post('/notes', (req, res) => {
const note = { text: req.body.body, title: req.body.title };
db.collection('notes').insert(note, (err, result) => {
if (err) {
res.send({ 'error': 'An error has occurred' });
} else {
res.send(result.ops[0]);
}
});
});
};
partially correct code
server.js (code that partially works & doesn't throw the db.collections error like my original server.js file )
const express = require('express');
const MongoClient = require('mongodb').MongoClient;
const bodyParser = require('body-parser');
const db = require('./config/db');
const app = express();
const port = 8000;
app.use(bodyParser.urlencoded({extened:true}));
MongoClient.connect(db.url,(err,database) =>{
if (err) return console.log(err)
//require('./app/routes')(app,{});
//check below line changed
require('./app/routes')(app, database);
app.listen(port,() => {
console.log("We are live on"+port);
});
})
Remove the node_modules folder and change mongodb version of your package.json
"mongodb": "^2.2.33"
and run below code :
npm install
change to this require('mongodb').MongoClient;

Node.JS Insert data to mongodb Web API , bodyParser issue

I need an API to android to insert data to mongodb , I'm following this , but
var song = req.body; TypeError: Cannot read property 'body' of undefined
I google few answer , which was need to install bodyParser , so I follow this to install bodyParser , but still get
var song = req.body; TypeError: Cannot read property 'body' of undefined
I'm not sure where I do wrong , please help
app code
var express = require('express'),
songs = require('./routes/route');
var app = express();
var bodyParser = require('body-parser');
var jsonParser = bodyParser.json();
app.post('/songs', jsonParser, function (req, res) {
if (!req.body) return res.sendStatus(400);
// create user in req.body
});
app.get('/', function (req, res) {
res.send('Hello World!');
});
app.listen(3000, function () {
console.log('Example app listening on port 3000!');
});
app.get('/songs',songs.addSong);
route cote
var mongoose = require('mongoose');
var mongo = require('mongodb');
var uri = "mongodb://XXXXXX:XXXXXXXX#ds061365.mongolab.com:61365/aweitest";
mongoose.connect(uri);
// we're connected!
var db = mongoose.connection.db;
var BSON = require('bson').BSONPure;
var body = require('body-parser');
db.on('error', console.error.bind(console, 'connection errrrrrrrror:'));
//db = mongoose.connection.db;
db.once('open', function() {
console.log("mongodb is connected!!");
});
exports.addSong = function(req, res) {
var song = req.body;
console.log('Adding song: ' + JSON.stringify(song));
db.collection('songs', function(err, collection) {
collection.insert(song, {safe:true}, function(err, result) {
if (err) {
res.send({'error':'An error has occurred'});
} else {
console.log('Success: ' + JSON.stringify(result[0]));
res.send(result[0]);
}
});
});
}
You're not using jsonParser in your GET /songs route, only your POST /songs route. However, GET requests typically do not have request bodies. Values are typically passed in the url as query parameters in those cases, so you will probably want to instead look in req.query.

Node emitters with express

I want to make serial work on backend. I want to select geo_unit and do another work and write response to client.
I read http://nodejs.org/docs/v0.4.7/api/events.html#events and Error: Can't set headers after they are sent to the client
Everything works fine when I send the requests slowly e.g. 1 in each 3 seconds.
But it doesnot work when i send the requests fast. and i get the following error.
Do i define something globally?
Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (http.js:691:11)
at ServerResponse.res.setHeader (E:\git\xxxxxx-nodejs\node_modules\express\node_modules\connect\lib\patch.js:63:22)
at ServerResponse.res.set.res.header (E:\git\xxxxxx-nodejs\node_modules\express\lib\response.js:527:10)
at ServerResponse.res.json (E:\git\xxxxxx-nodejs\node_modules\express\lib\response.js:194:36)
at EventEmitter. (E:\git\xxxxxx-nodejs\routes\api_scrapper.js:17:17)
at EventEmitter.emit (events.js:117:20)
at ScrapperAPI.externalLocationCallback (E:\git\xxxxxx-nodejs\routes\api_scrapper.js:27:20)
at Query._callback (E:\git\xxxxxx-nodejs\routes\api_scrapper.js:51:21)
at Query.Sequence.end (E:\git\xxxxxx-nodejs\node_modules\mysql\lib\protocol\sequences\Sequence.js:78:24)
at Query._handleFinalResultPacket (E:\git\xxxxxx-nodejs\node_modules\mysql\lib\protocol\sequences\Query.js:143:8)
I am using the following code :
var express = require('express'),
http = require('http'),
path = require('path');
var app = module.exports = express();
var server = require('http').createServer(app);
var io = require('socket.io').listen(server);
var request = require('request');
var cheerio = require('cheerio');
var mysql = require('mysql');
var pool = mysql.createPool({
host : 'localhost',
user : 'root',
database :'evevgez_development',
password : 'root',
// socketPath : '/var/run/mysqld/mysqld.sock'
});
var sahibinden = require('./routes/my_scrapper').newScrapperAPI(pool);
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.static(path.join(__dirname, 'public')));
app.use(app.router);
app.use(express.errorHandler());
app.get('/node1', sahibinden.scrap);
server.listen(app.get('port'), function () {
console.log('Express server listening on port ' + app.get('port'));
});
and myModule is like that
var request = require('request');
var cheerio = require('cheerio');
var iconv = require('iconv-lite');
var EventEmitter = require('events').EventEmitter;
var emitter= new EventEmitter();
function ScrapperAPI(pool) {
this.scrap = function (req, res,next) {
var query = req.query;
console.log('req.params:'+req.query);
console.log('IL_ID:'+query.il_id);
emitter.emit('location',query);
emitter.on('success',function(rows){
res.json(rows);
});
};
emitter.on('location',function(query){
console.log('quey1:'+query);
getExternalLocation(query )
});
var getExternalLocation = function (query ) {
try {
pool.getConnection(function (err, connection) {
console.log('query:'+query);
connection.query("select * from external_geo_units where geo_unit_id = ? ",query.il_id, function (err, rows) {
console.log(err);
if (err) callback(err);
emitter.emit('success',rows);
connection.release();
});
});
} catch (e) {
console.log(e);
}
};
}
module.exports.newScrapperAPI = function (pool) {
return new ScrapperAPI(pool);
}
Using an EventEmitter in this way isn't the best solution for what you're doing, since you're just using it within a request to make a database call and return some rows -- something that could be more easily and simply done with just callbacks.
However if you want to keep the global EventEmitter, you have to switch the on in emitter.on('success' and emitter.on('location' to once instead, to ensure they only get called once per request.

Resources