How should I parse URL parameters using Node JS express? - node.js

I would like to pass the lat lon from this URL http://localhost:8080/fp?lon=103.742463567216646&lat=1.336711421273283. Where should I place the "req.query.lon" and "req.query.lat" in the following code?
I am hoping to parse the users input in the URL link so that I can dynamically retrieve from the database.
const {Client} = require("pg")
const express = require ("express")
const url=require('url')
const fs= require('')
const app = express();
app.use(express.json())
const client = new Client({
"user": "xxx",
"password" : "xxx",
"host" : "xxx",
"port" : xxx,
"database" : "xxx"
})
//app.get("/", (req, res) => res.sendFile(`${__dirname}/index.html`))
app.get("/fp", async (req, res) => {
//const lon = 103.742463567216646;
//const lat = 1.336711421273283;
//const lon = req.query.lon;
//const lat = req.query.lat;
const rows = await readTodos ();
res.send(JSON.stringify(rows))
})
app.listen(8080, () => console.log("Web server is listening.. on port 8080"))
start()
async function start() {
await connect();
}
async function connect() {
try {
await client.connect();
}
catch(e) {
console.error(`Failed to connect ${e}`)
}
}
async function readTodos() {
try {
const results = await client.query("SELECT ST_AsText(ST_Force2D(geom)) FROM fp ORDER BY geom <-> ST_SetSRID(ST_MakePoint("+lon+ ","+lat+ "), 3993) LIMIT 1;");
return results.rows;
}
catch(e){
return [];
}
}

Express parses it by default and store them in req.query.
Accessing req.query.<key> will give you the value you are looking for.
For instance, in your example, express will store it inside req.query.lon and req.query.lat.
So, actually you access them right in the request handler of /fp, just comment out the access to these variables and pass them as parameters to readTodos():
app.get("/fp", async (req, res) => {
const lon = req.query.lon;
const lat = req.query.lat;
const rows = await readTodos(lon, lat);
res.send(JSON.stringify(rows))
})
async function readTodos(lon, lat) {
try {
const results = await client.query("SELECT ST_AsText(ST_Force2D(geom)) FROM fp ORDER BY geom <-> ST_SetSRID(ST_MakePoint("+lon+ ","+lat+ "), 3993) LIMIT 1;");
return results.rows;
}
catch(e){
return [];
}
}

Related

caching query with redis

i need to cache a query with redis and node js , the database is aws s3 ,the problem here as a noob ,i will recive the query as a string, i need to encode the keys in the body request so when i will later try to fetsch the data i will use one of those keys(they need to be seperated with '/') can anyone help me with that and bunch of thanks.
here is what i' tried to do:
const { default: axios } = require('axios');
const express = require('express');
const redisClient = require('./helper/Client')
const app = express();
const port = process.env.PORT || 3000
app.use(express.json());
async function fetchApi(species){
const apiResponse = await axios.get(`https://www.fishwatch.gov/api/species/${species}`)
console.log('request sent successfully');
return apiResponse.data
}
async function getSpeciesData(req, res) {
const species = req.body;
const keys = Object.keys(species);
const encodedParams = {};
for (const key of keys) {
const encodedKey = Buffer.from(key).toString('base64');
encodedParams[encodedKey] = species[key];
}
const key = JSON.stringify(encodedParams);
let resultat;
let isCached = false;
const cachedResponse = await redisClient.get(key);
if (cachedResponse) {
isCached = true;
const decodedResponse = Buffer.from(cachedResponse, 'base64').toString('utf-8');
resultat = JSON.parse(decodedResponse);
res.send({
fromCache: isCached,
data: resultat
});
console.log(cachedResponse);
} else {
const responseData = await fetchApi(keys.join('/'));
const encodedResponseData = Buffer.from(JSON.stringify(responseData)).toString('base64');
redisClient.SETEX(key, 3600, encodedResponseData);
res.send(responseData);
}
}
app.post("/fish", getSpeciesData);
app.listen(port, () => {
console.log(`Listening on ${port}`);
});

NodeJS+Express+SQL Server backend application Error : Incorrect Syntax near '83' , Incorrect Syntax near '68' etc

In my application I get the following errors when I'm trying to reach GET, PUT, DELETE routes (tried POSTMAN and VSCode REST Server):
Error 1:
GET by ID : `Incorrect Syntax near '83'.`
Error 2:
GET ALL : `Incorrect Syntax near '83'.`
Error 3:
PUT : `Incorrect syntax near '85'.`
Error 4:
DELETE : `Incorrect syntax near '68'.`
I have googled the error but most of them are related to spacing errors in parameters in the SQL query but I have checked mine and the queries I have are all correct compared to those.
I suspect if this related to any SQL Server related encoding but not sure.
Below are some of my coding as a start to investigate:
eventController.js
'use strict';
const eventData = require('../data/events');
const getEvents = async (req, res, next) => {
try {
const events = await eventData.getEvents();
res.send(events);
}catch (error) {
res.status(400).send(error.message);
}
}
const getEvent = async (req, res, next) => {
try {
const eventId = req.params.id;
const oneEvent = await eventData.getById(eventId);
res.send(oneEvent)
} catch (error) {
res.status(400).send(error.message)
}
}
const updateEvent = async (req, res, next) => {
try {
const eventId = req.params.id;
const data = req.body;
const updated = await eventData.updateEvent(eventId, data);
res.send(updated);
} catch (error) {
res.status(400).send(error.message)
}
}
const deleteEvent = async (req, res, next) => {
try {
const eventId = req.params.id;
const deletedevent = await eventData.deleteEvent(eventId);
res.send(deletedevent);
} catch (error) {
res.status(400).send(error.message)
}
}
module.exports = {
getEvents,
getEvent,
updateEvent,
deleteEvent
}
eventslist.sql
SELECT [ord_type],
[ord_no],
[line_seq_no],
[lvl_no],
[cmt_type],
[cmt_seq_no],
[cmt],
[CMT_DOC_TYPE],
[EXTRA_1],
[extra_2],
[extra_3],
[extra_4],
[extra_5],
[extra_6],
[extra_7],
[extra_8],
[extra_9],
[extra_10],
[extra_11],
[extra_12],
[extra_13],
[extra_14],
[extra_15],
[FILLER_0001],
[ID],
[is_ext],
[RowVersion]
FROM [100].[dbo].[OELINCMT_SQL]
utils.js
'use strict';
const fs = require('fs-extra');
const {join} = require('path');
const loadSqlQueries = async (folderName) => {
const filePath = join(process.cwd(), 'data', folderName);
const files = await fs.readdir(filePath);
const sqlFiles = await files.filter(f => f.endsWith('.sql'));
const queries = {};
for (const sqlFile of sqlFiles) {
const query = await fs.readFileSync(join(filePath, sqlFile));
queries[sqlFile.replace(".sql", "")] = query
}
return queries;
}
module.exports = {
loadSqlQueries
}
UPDATE : Added data/events
index.js
'use strict';
const utils = require('../utils');
const config = require('../../config');
const sql = require('mssql');
const getEvents = async () => {
try {
let pool = await sql.connect(config.sql);
const sqlQueries = await utils.loadSqlQueries('events');
const list = await pool.request().query(sqlQueries.eventslist);
return list.recordset;
} catch (error) {
return error.message;
}
}
const getById = async (eventId) => {
try {
let pool = await sql.connect(config.sql);
const sqlQueries = await utils.loadSqlQueries('events');
const oneEvent = await pool.request()
.input('eventId', sql.Char(8), eventId)
.query(sqlQueries.eventbyId);
return oneEvent.recordset;
} catch (error) {
return error.message;
}
}
const updateEvent = async (eventId, eventData) => {
try {
let pool = await sql.connect(config.sql);
const sqlQueries = await utils.loadSqlQueries('events');
const update = await pool.request()
.input('eventId', sql.Char(8), eventId)
.input('cmt', sql.NVarChar(4000), eventData.cmt)
.query(sqlQueries.updateEvent);
return update.recordset;
} catch (error) {
return error.message
}
}
const deleteEvent = async (eventId) => {
try {
let pool = await sql.connect(config.sql);
const sqlQueries = await utils.loadSqlQueries('events');
const deleted = await pool.request()
.input('eventId', sql.Char(8), eventId)
.query(sqlQueries.deleteEvent);
return deleted.recordset;
} catch (error) {
return error.message
}
}
module.exports = {
getEvents,
getById,
updateEvent,
deleteEvent
}
eventbyId.sql
SELECT [ord_type]
,[ord_no]
,[line_seq_no]
,[lvl_no]
,[cmt_type]
,[cmt_seq_no]
,[cmt]
,[CMT_DOC_TYPE]
,[EXTRA_1]
,[extra_2]
,[extra_3]
,[extra_4]
,[extra_5]
,[extra_6]
,[extra_7]
,[extra_8]
,[extra_9]
,[extra_10]
,[extra_11]
,[extra_12]
,[extra_13]
,[extra_14]
,[extra_15]
,[FILLER_0001]
,[ID]
,[is_ext]
,[RowVersion]
FROM [100].[dbo].[OELINCMT_SQL]
WHERE [ord_no] = #eventId
Request for GET ALL via POSTMAN
Request for GET by ID via POSTMAN
Request for GET ALL via REST Server
RAW Body of GET ALL request
RAW Body of GET by ID request

Get param in URL without callback function

so I know how to get params from URL the normal way:
router.get('/products/:id', (request, response, next) => {
let id = request.params.id;
But when I want to refactor the code to many files, the code becomes something like:
const productService = require('../services/productService');
router.get('/products/:id', productService.getProductList);
How can I get the "id" from URL now?
The productService.js file:
var mongodb = require('mongodb');
const db = require('../models/mongoUtil.js').getDb();
const getProductList = async (request, response) => {
try {
let id = request.params.id;
let object_id = new mongodb.ObjectId(id);
const result = await db.collection('product_list').findOne({ '_id': object_id });
response.json(result);
console.log(result);
} catch (err) {
console.log(err);
}
};
module.exports = {
getProductList
};
Thank you. I am new to Node Js.

Nodejs return result from function is empty promise

I am trying to use Nodejs tron library to create pair of wallet address and here is my code:
app.js
var app = require('express')()
var http = require('http').createServer(app)
var wallet_engine = require('./function')
app.get('/', function (req, res) {
result = wallet_engine.create_wallet_trx()
console.log(result)
res.send(result)
})
//////server listen
http.listen(8443, function () {
console.log('listening on *:8443')
})
and here is my function.js
module.exports = {
create_wallet_trx: function () {
////////generate TRX Address
var { HdTronPayments } = require('#faast/tron-payments')
var keys = HdTronPayments.generateNewKeys()
var tronPayments = new HdTronPayments({ hdKey: keys.xprv })
var address = tronPayments.getPayport(356)
var privateKey = tronPayments.getPrivateKey(356)
var trx_wallet = { privateKey: privateKey, address: address }
console.log(trx_wallet)
return trx_wallet
},
}
The problem is when i check console.log(trx_wallet) the result is there and i can see generated public and private key, also after returning data, console.log(result) is displaying data, but res.send(result) shows me empty json.
this is console.log() results
{
privateKey: Promise {
'B88BB56DAB80DB681765A0C07197DD23BB8E2FAD195BF9D0ECD09F5F8FC54297'
},
address: Promise { { address: 'TYCJSKERHReUXacw9wLorZYLDoijevvsVK' } }
}
and this is the result on my browser:
{"privateKey":{},"address":{}}
i know this is because of Nodejs Async system and i should wait to promise gets the value but i don't know how to wait for promise to get complete and then prints the result on my browser screen.
You are doing good but here many calls are asynchronous that's for you facing problem.
you should use async await or then as i did bellow it may help you..
// app js
var app = require('express')()
var http = require('http').createServer(app)
var wallet_engine = require('./function')
app.get('/', function (req, res) {
result = wallet_engine.create_wallet_trx().then(data=>{
res.json(data);
}).catch(err=>{
console.log(err);
})
})
//////server listen
http.listen(8443, function () {
console.log('listening on *:8443')
})
// function.js
var { HdTronPayments } = require('#faast/tron-payments')
module.exports = {
create_wallet_trx: async function () {
var keys = await HdTronPayments.generateNewKeys()
var tronPayments = await new HdTronPayments({ hdKey: keys.xprv })
var address = await tronPayments.getPayport(356)
var privateKey = await tronPayments.getPrivateKey(356)
var trx_wallet = { privateKey: privateKey, address: address }
return trx_wallet
}
}
result: {"privateKey":"92ACAECFE00E9F90E330A6B031F10365F29AFDD503922CC99CA8704F1BA53432","address":{"address":"TGfsHx4VU6B36AwUy8Bqt6edoNnUHpMtSQ"}}

expressjs returning controller object to res.send

I have a controller that makes an api call (few seconds delay) and then returns a JSON object that I want to send and appear on my view page. At the moment I am able to return the object and successfully load the route, but the object is not appearing on my browser page (status code: 200) and I'm not sure what I might be missing. Provided below is my route and controller.
Controller:
var express = require('express');
var apiRouter = express.Router();
var googleAnalytics = require('../google-analytics');
const { checkToken } = require("./components/token-validator");
apiRouter.use(checkToken);
apiRouter.get('/ga', function(req, res){
res.send(googleAnalytics())
});
module.exports = apiRouter;
Controller (googleAnalytics):
module.exports = () => {
console.log("google-analytics.js")
const {google} = require('googleapis');
const analyticsreporting = google.analyticsreporting('v4');
const view_id = '*view-id(';
... // resource: req information
analyticsreporting.reports.batchGet({
resource: req
}, (err, result) => {
if(err){
if(err.errors){
console.log(err.errors[0].message)
} else {
console.log(err)
}
} else {
return result.data;
}
//console.log("BREAK IN CONSOLE")
//console.log(err, result)
})
}
Object E.g.:
{"reports":[{"columnHeader":{"dimensions":["ga:sourceMedium"],"metricHeader":{"metricHeaderEntries":
...
]}}
You are not returning anything from the google-analytics.js. You need to make the function return a promise or use callback. analyticsreporting.reports.batchGet returns a promise so it is pretty easy to do that.
module.exports = () => {
console.log("google-analytics.js")
const {google} = require('googleapis');
const analyticsreporting = google.analyticsreporting('v4');
const view_id = '*view-id(';
... // resource: req information
return analyticsreporting.reports.batchGet({
resource: req
});
}
Now, in your /ga route, you can use async-await:
apiRouter.get('/ga', async function(req, res){
res.send(await googleAnalytics())
});

Resources