Express REST API response methods are not recognized - json

I have this really simple get request that returns json that I am trying to implement. I have followed the tutorials for Express Web Framework REST API, but for some reason I keep getting the same error
ERROR:
TypeError: res.status is not a function
or
TypeError: res.json is not a function
index.js:
var express = require('express');
var router = express.Router();
var pg = require('pg');
var connectionString = 'pg://postgres:postgres#postgres/feed';
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
router.get('/api/leaderboard', function(resp, req){
var results = [];
pg.connect(connectionString, function(err, client, done){
if(err){
done();
console.log(err);
return res.status(500).json({ success: false, data: err});
}
var query = client.query("SELECT * FROM log WHERE (logged >= date_trunc('week', CURRENT_TIMESTAMP - interval '1 week') AND logged <= date_trunc('week', CURRENT_TIMESTAMP));");
var counter = 0;
var b1 = {};
var b2 = {};
var b3 = {};
var b4 = {};
b1.energy_sum_week = 0;
b2.energy_sum_week = 0;
b3.energy_sum_week = 0;
b4.energy_sum_week = 0;
b1.zne_sum_week = 30000;
b2.zne_sum_week = 30000;
b3.zne_sum_week = 30000;
b4.zne_sum_week = 30000;
query.on('row', function(row){
//results.push(row);
if(row['address'] == 215){
b1.energy_sum_week = row['kitchen'] + row['plugload'] + row['lights'] + row['ev'] + row['hvac'] + row['instahot'] - row['solar'];
}
else if (row['address'] == 1590) {
b2.energy_sum_week = row['kitchen'] + row['plugload'] + row['lights'] + row['ev'] + row['hvac'] + row['instahot'] - row['solar'];
} else if (row['address'] == 1605) {
console.log(row);
b3.energy_sum_week = row['kitchen'] + row['plugload'] + row['lights'] + row['ev'] + row['hvac'] + row['instahot'] - row['solar'];
} else if (row['address'] == 1715) {
b4.energy_sum_week = row['kitchen'] + row['plugload'] + row['lights'] + row['ev'] + row['hvac'] + row['instahot'] - row['solar'];
}
});
query.on('end', function(){
done();
//make zne lower than everything
results.push(b1);
results.push(b2);
results.push(b3);
results.push(b4);
resp.json(results);
});
});
});
module.exports = router;
It seems like it can't recognize the response object. Tried a bunch of different things like passing in the request and response's to the query callbacks, and using promises.
Getting kinda desperate here :/

The res variable doesn't exist in the current context, you probably expect that the line
router.get('/api/leaderboard', function(resp, req){
had this form
router.get('/api/leaderboard', function(req, res){

You are passing resp as the req object and the req as the resp object.
Try changing the order.
router.get('/api/leaderboard', function(req, resp){...}

Related

Extract data from JSON within Lambda so it's not undefined

Looking for advice / second opinion. I'm trying to pass JSON via HTTP API (api gateway) > Lambda. I'm receiving the data (pic of Cloudwatch), getting undefined when trying to extract values. The file is being written to S3, but undefined.
I included Lambda code, picture of Cloudwatch logs. I'm about there :) . Newbie here...
Logs
Lambda Code
var AWS = require('aws-sdk');
var s3 = new AWS.S3();
exports.handler = async (event, context, callback) => {
var bucketName = process.env.bucketName;
var folder = process.env.folder;
var filename = getFileName();
console.log("Filename:" + filename);
var raw = JSON.stringify(event.body);
console.log("raw after stringify:" + raw);
var results = JSON.parse(raw);
console.log("results:" + results);
let firstname = results.firstName;
console.log("firstName:" + firstname);
let lastname = results.lastName;
console.log("lastName:" + lastname);
let message = results.Message;
console.log("Message:" + message);
var content = message + "," + firstname + "," + lastname;
console.log("content:" + content);
var keyName = getKeyName(folder, filename);
var params = { Bucket: bucketName, Key: keyName, Body: content };
s3.putObject(params, function (err, data) {
if (err)
console.log(err)
else
console.log("Successfully saved object to: " + bucketName + "/" + keyName);
});
function getKeyName(folder, filename) {
return folder + '/' + filename;
}
function getFileName() {
var _uuid = uuidv4();
var _date = Date.now();
return _uuid + "-" + _date;
}
function uuidv4() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
var html = '<html><head><title>Prayer received result</title></head>' +
'<body><h1>Your Prayer has been received!</h1></body></html>';
//callback(null, res); - use this when using proxy model
callback(null, html);
};
Made the following changes.
//var raw = JSON.stringify(event.body);
//console.log("raw after stringify:" + raw);
var results = JSON.parse(event.body);
console.log("results:" + results);
Hope this helps others. I'm newer as of this post to Lambda, JSON.

Why my Node.Js code not giving response in first request while taking value from user?

In this code, I am sending a POST request to the server which contains email-id and using that email-id I am retrieving Information from the database.
I am testing this from postman "http://127.0.0.1:80/echo" POST request after sending a request first time it shows in response
{
"source": "webhook-echo-sample"
}
and the second time it gives me proper result
{
"speech": "Name:xyz Mobile.no:123456789Address:qweCollege:azx Email:cvb#gmail.com",
"source": "webhook-echo-sample"
}
Why my first request to API is going fail?
"use strict";
const express = require("express");
const restService = express();
const bodyParser = require("body-parser");
const os = require('os');
var mysql = require("mysql");
var final;
var Name = "Name:";
var Mobileno = "Mobile.no:";
var College = "College:";
var Address = "Address:";
var Email = "Email:";
restService.use(
bodyParser.urlencoded({
extended: true
})
);
restService.use(bodyParser.json());
restService.post("/echo", function(req, res) {
var con = mysql.createConnection({
host: "abc.com",
user: "xyz123",
password: "123456",
database: "seller1"
});
var email = req.body.result.parameters.echoText
var sql = 'SELECT * FROM seller1 WHERE email_id=' + mysql.escape(email);
con.query(sql, function(error, results) {
if (!error) {
for (var i = 0; i <= results.length - 1; i++) {
final = Name + results[i].Name + "\n" + Mobileno + results[i].mobile_no + "\n" + Address + results[i].Address + "\n" + College + results[i].College + "\n" + Email + results[i].email_id;
}
} else {
return [];
}
});
return res.json({
"speech": final,
"source": "webhook-echo-sample"
});
});
restService.listen(process.env.PORT || 80, function() {
console.log("Server up and listening");
});
I think it's because of javascript Asynchronous nature
try sending the response inside !error check as shown below
restService.post("/echo", function(req, res) {
var con = mysql.createConnection({
host: "abc.com",
user: "xyz123",
password: "123456",
database: "seller1"
});
var email = req.body.result.parameters.echoText
var sql = 'SELECT * FROM seller1 WHERE email_id=' + mysql.escape(email);
con.query(sql, function(error, results) {
if (!error) {
for (var i = 0; i <= results.length - 1; i++) {
final = Name + results[i].Name + "\n" + Mobileno + results[i].mobile_no + "\n" + Address + results[i].Address + "\n" + College + results[i].College + "\n" + Email + results[i].email_id;
}
return res.json({
"speech": final,
"source": "webhook-echo-sample"
});
} else {
return [];
}
});
});

Pagination in nodejs with mysql

In my project I need to query the db with pagination and provide user the functionality to query based on current search result. Something like limit, I am not able to find anything to use with nodejs. My backend is mysql and I am writing a rest api.
You could try something like that (assuming you use Express 4.x).
Use GET parameters (here page is the number of page results you want, and npp is the number of results per page).
In this example, query results are set in the results field of the response payload, while pagination metadata is set in the pagination field.
As for the possibility to query based on current search result, you would have to expand a little, because your question is a bit unclear.
var express = require('express');
var mysql = require('mysql');
var Promise = require('bluebird');
var bodyParser = require('body-parser');
var app = express();
var connection = mysql.createConnection({
host : 'localhost',
user : 'myuser',
password : 'mypassword',
database : 'wordpress_test'
});
var queryAsync = Promise.promisify(connection.query.bind(connection));
connection.connect();
// do something when app is closing
// see http://stackoverflow.com/questions/14031763/doing-a-cleanup-action-just-before-node-js-exits
process.stdin.resume()
process.on('exit', exitHandler.bind(null, { shutdownDb: true } ));
app.use(bodyParser.urlencoded({ extended: true }));
app.get('/', function (req, res) {
var numRows;
var queryPagination;
var numPerPage = parseInt(req.query.npp, 10) || 1;
var page = parseInt(req.query.page, 10) || 0;
var numPages;
var skip = page * numPerPage;
// Here we compute the LIMIT parameter for MySQL query
var limit = skip + ',' + numPerPage;
queryAsync('SELECT count(*) as numRows FROM wp_posts')
.then(function(results) {
numRows = results[0].numRows;
numPages = Math.ceil(numRows / numPerPage);
console.log('number of pages:', numPages);
})
.then(() => queryAsync('SELECT * FROM wp_posts ORDER BY ID DESC LIMIT ' + limit))
.then(function(results) {
var responsePayload = {
results: results
};
if (page < numPages) {
responsePayload.pagination = {
current: page,
perPage: numPerPage,
previous: page > 0 ? page - 1 : undefined,
next: page < numPages - 1 ? page + 1 : undefined
}
}
else responsePayload.pagination = {
err: 'queried page ' + page + ' is >= to maximum page number ' + numPages
}
res.json(responsePayload);
})
.catch(function(err) {
console.error(err);
res.json({ err: err });
});
});
app.listen(3000, function () {
console.log('Example app listening on port 3000!');
});
function exitHandler(options, err) {
if (options.shutdownDb) {
console.log('shutdown mysql connection');
connection.end();
}
if (err) console.log(err.stack);
if (options.exit) process.exit();
}
Here is the package.json file for this example:
{
"name": "stackoverflow-pagination",
"dependencies": {
"bluebird": "^3.3.3",
"body-parser": "^1.15.0",
"express": "^4.13.4",
"mysql": "^2.10.2"
}
}
I taked the solution of #Benito and I tried to make it more clear
var numPerPage = 20;
var skip = (page-1) * numPerPage;
var limit = skip + ',' + numPerPage; // Here we compute the LIMIT parameter for MySQL query
sql.query('SELECT count(*) as numRows FROM users',function (err, rows, fields) {
if(err) {
console.log("error: ", err);
result(err, null);
}else{
var numRows = rows[0].numRows;
var numPages = Math.ceil(numRows / numPerPage);
sql.query('SELECT * FROM users LIMIT ' + limit,function (err, rows, fields) {
if(err) {
console.log("error: ", err);
result(err, null);
}else{
console.log(rows)
result(null, rows,numPages);
}
});
}
});
Was looking for a quick solution. maybe would be useful for someone.
SELECT id FROM complexCoding LIMIT ? OFFSET ?
",req.query.perpage,((req.query.page-1) * req.query.perpage)
Do not forget to paginate according to the total count of id divided by perpage
I wrote a pagination class in order to use it on different pages, I used bootstrap to style the links, you can change it if you're not using bootstrap.
Items route
router.get('/items/:page',(req,res) => {
const db = require('mysql'),
Pagination = require('./pagination'),
// Get current page from url (request parameter)
page_id = parseInt(req.params.page),
currentPage = page_id > 0 ? page_id : currentPage,
//Change pageUri to your page url without the 'page' query string
pageUri = '/items/';
/*Get total items*/
db.query('SELECT COUNT(id) as totalCount FROM items',(err,result)=>{
// Display 10 items per page
const perPage = 10,
totalCount = result[0].totalCount;
// Instantiate Pagination class
const Paginate = new Pagination(totalCount,currentPage,pageUri,perPage);
/*Query items*/
db.query('SELECT * FROM items LIMIT '+Paginate.perPage+' OFFSET '+Paginate.start,(err,result)=>{
data = {
items : result,
pages : Paginate.links()
}
// Send data to view
res.render('items',data);
});
});
});
On items view, just print "pages" to generate pagination links
{{ pages }}
pagination.js >> Add this code to pagination.js and import it to any page you want to use pagination
class Pagination{
constructor(totalCount,currentPage,pageUri,perPage=2){
this.perPage = perPage;
this.totalCount =parseInt(totalCount);
this.currentPage = parseInt(currentPage);
this.previousPage = this.currentPage - 1;
this.nextPage = this.currentPage + 1;
this.pageCount = Math.ceil(this.totalCount / this.perPage);
this.pageUri = pageUri;
this.offset = this.currentPage > 1 ? this.previousPage * this.perPage : 0;
this.sidePages = 4;
this.pages = false;
}
links(){
this.pages='<ul class="pagination pagination-md">';
if(this.previousPage > 0)
this.pages+='<li class="page-item"><a class="page-link" href="'+this.pageUri + this.previousPage+'">Previous</a></li>';
/*Add back links*/
if(this.currentPage > 1){
for (var x = this.currentPage - this.sidePages; x < this.currentPage; x++) {
if(x > 0)
this.pages+='<li class="page-item"><a class="page-link" href="'+this.pageUri+x+'">'+x+'</a></li>';
}
}
/*Show current page*/
this.pages+='<li class="page-item active"><a class="page-link" href="'+this.pageUri+this.currentPage+'">'+this.currentPage+'</a></li>';
/*Add more links*/
for(x = this.nextPage; x <= this.pageCount; x++){
this.pages+='<li class="page-item"><a class="page-link" href="'+this.pageUri+x+'">'+x+' </a></li>';
if(x >= this.currentPage + this.sidePages)
break;
}
/*Display next buttton navigation*/
if(this.currentPage + 1 <= this.pageCount)
this.pages+='<li class="page-item"><a class="page-link" href="'+this.pageUri+this.nextPage+'">Next</a></li>';
this.pages+='</ul>';
return this.pages;
}
}
module.exports = Pagination;

Node js + postgresql : Generate JSON with Node.js with multiple postgresql

I have just started coding with node.js, I understand that node.js is asynchronous but not sure how to deal with this problem.
I'm querying postgresql and building a JSON as follows,
I added my code :
var express = require('express');
var router = express.Router();
var pg = require('pg');
var client = require('../routes/database.js');
var cookieParser = require('cookie-parser');
var dateFormat = require('date-format');
var async = require('async');
var today = dateFormat(new Date());
router.post('/conversation/my', function(req, res) {
var userId = 59;
var limit = 10;
var offset = 0;
var postgresql = "select id from conversation where party_id = '" + userId + "' and reply_id = 0 order by created_on desc limit " + limit + " offset " + offset + "";
var postsJSON = { };
var arr = new Array();
client.query(postgresql, function(err, data) {
if (err) {
console.log(err);
return rollback(client);
}
var rows = data.rows;
for ( i = 0; i < rows.length; i++) {
var post = rows[i];
var post_obj = {};
post_obj.id = post.id;
getConversationResponse(post.id, function(err, res) {
if (!err) {
post_obj.actor = res;
arr.push(post_obj);
console.log(JSON.stringify(arr));
res.send({
data : arr
});
}
});
}
});
});
function getConversationResponse(conversation_id, cb) {
client.query('SELECT * FROM people WHERE id ='+conversation_id+';', function(err, actor) {
client.query('SELECT * FROM users WHERE id ='+conversation_id+';', function(err, user) {
var actor_obj = {};
actor_obj.id = user.id;
actor_obj.name = user.name;
actor_obj.email = user.email;
client.end();
cb (null,actor_obj);
});
});
}
module.exports = router;
But i am getting error :
{ [Error: write EPIPE] code: 'EPIPE', errno: 'EPIPE', syscall: 'write' }
events.js:72
throw er; // Unhandled 'error' event
^
Error: write EPIPE
at errnoException (net.js:901:11)
at Object.afterWrite (net.js:718:19)
npm ERR! weird error 8
npm WARN This failure might be due to the use of legacy binary "node"
npm WARN For further explanations, please read
/usr/share/doc/nodejs/README.Debian
Your client.end(); should not be in the function. It should be after the first client.query for conversations has completed. Currently what happens is that for each conversation, you call the function to get the people/users, where you end the client. So the next conversation row cannot get the people/users.
Also, ideally you should join the three tables and get all the data in one shot.
var postgresql = "select id, people.*, users.* from conversation, people, users where party_id = '" + userId + "' and people.id=conversation.id and users.id=conversations.id and reply_id = 0 order by created_on desc limit " + limit + " offset " + offset + "";

Unable to get value from JSON after mySQL

var sender_username = req.session.user_id;
var recipient_username = req.body.recipient_username;
var content = req.body.content;
var sql = ' SELECT sender_username, recipient_username, COUNT(recipient_username) as count FROM message WHERE sender_username = "'+sender_username+'" AND recipient_username = "'+recipient_username+'" GROUP BY sender_username LIMIT 1 ';
var message_no = 0;
var data;
connection.query(sql, function(err, result) {
if (err) {
res.send(err);
}
else {
data = result;
// res.send(data); < - this works
// res.send(result); <- this works
// res.send(result.count); <- undefined
}
});
res.send(data); // undefined (can't seem to save to variable after connection.query())
The res.send(result); seems to work. It gives:
[{"sender_username":"sender","recipient_username":"recipient","count":2}]
I am just trying to get the value for count and save that to a variable, but things like result.count are returning undefined for some reason.
It's because the JSON is an array, so you should access it like the following
res.send(result[0].count);