A lot of routes in one module.exports - node.js

// app.js
const express = require("express");
const app = express();
let jsonController = require("./jsonController.js");
app.get("/readJson", jsonController);
app.listen(1337, () => {
console.log("Listening");
});
// jsonController.js
module.exports = () => {
< --- here --- >
};
Can I find out in <--- here ---> from route it was called?
Something like this:
// jsonController.js
module.exports = () => {
if called from "/readJson" {
(res, req) => {
res.send("FROM READJSON"); }
}
};
Thanks for any help.

What you need is req.route.path.
If controller is configured as app.get("/readJson", jsonController); and app.get("/readJson2", jsonController);, then in jsonController, you can get how it is called by:
// jsonController.js
module.exports = (req, res) => {
let routePath = req.route.path;
if (routePath === '/readJson') {
res.send('From readJson');
} else if (routePath === '/readJson2') {
res.send('From readJson2');
}
};

Related

Azure: INFO - Waiting for response to warmup request for container ... Elapsed time = x sec

My app fails on prod and can't find a way how to fix. It works on another environments.
Some logs from the console:
2022-08-22T23:56:05.760Z INFO - Waiting for response to warmup request for container projectprod-fe_0_fd84e. Elapsed time = [225.2643051] sec
2022-08-22T23:56:35.818Z ERROR - Container projectprodfe_0_fd84e for site teamgullitpreview-fe did not start within expected time limit. Elapsed time = 255.322965 sec
It is next.js app and I create middlewares for it.
const next = require('next');
const { parse } = require('url');
nextMiddleware
async function nextMiddleware(dev = false) {
const app = next({ dev });
const handle = app.getRequestHandler();
await app.prepare();
return function nextHandler(req, res) {
const parsedUrl = parse(req.url, true);
handle(req, res, parsedUrl);
};
}
redirectMiddleware
const path = require('path');
const fs = require('fs');
const staticFiles = ['_next', '/', 'images', 'api'];
const getRedirect = async (srcPath) => {
try {
const url = `${process.env.NEXT_PUBLIC_apiUrl}/redirect?path=${srcPath}`;
const response = await fetch(url);
const json = await response.json();
return json;
} catch (e) {
throw new Error(e);
}
};
function redirecter(pathname) {
return new Promise((resolve, reject) => {
const pathParts = pathname.split('/');
if (staticFiles.indexOf(pathParts[1]) > -1) {
resolve({
shouldRedirect: false,
redirectData: {},
});
} else {
const possibleFile = `${path.resolve(
__dirname,
'../../public',
)}${pathname}`;
if (fs.existsSync(possibleFile)) {
resolve({
shouldRedirect: false,
redirectData: {},
});
} else {
getRedirect(pathname)
.then((result) => {
resolve({
shouldRedirect: true,
redirectData: result,
});
})
.catch((e) => {
reject(e);
});
}
}
});
}
async function redirectMiddleware(req, res, next) {
const parsedUrl = parse(req.url, true);
const { pathname } = parsedUrl;
try {
const { shouldRedirect, redirectData } = await redirecter(pathname);
if (shouldRedirect && redirectData.destination) {
const redirectUri = `${process.env.NEXT_PUBLIC_hostname}${
redirectData.type ? redirectData.type : ''
}${redirectData.destination}`;
res.writeHead(redirectData.statusCode[0], {
Location: redirectUri,
});
res.end();
}
} catch (e) {
next();
} finally {
next();
}
}
What I do wrong in this file or whenever?
const http = require('http');
const express = require('express');
const redirectMiddleware = require('./src/server/redirectMiddleware');
const nextMiddleware = require('./src/server/nextMiddleware');
const port = process.env.PORT || 3000;
async function bootstrap() {
const isDevelopment = process.argv.includes('--dev');
const app = express();
app.use(await redirectMiddleware);
app.use(await nextMiddleware(isDevelopment));
const server = http.createServer(app);
server.listen(port, (err) => {
if (err) throw err;
console.log(`> Ready on http://localhost:${port}`);
});
}
bootstrap().catch((err) => {
console.error('something went wrong booting up the server.');
console.error(err);
process.exit(1);
});
I have no idea what's wrong and how to debugg it. Is anyone who experienced it before?

How to I dynamically insert key and value in JSON in the response of NodeJs API

This is the Input I am providing
{
"cities" : [
"kolkata",
"mumbai",
"chennai"
]
}
and this is the response I am receiving.
{
"weather": [
{
"chennai": "30C"
},
{
"mumbai": "27C"
},
{
"kolkata": "26C"
}
]
}
I want a response somewhat like
{
"weather" : {
"kolkata" : "26C",
"mumbai": "27C",
"chennai": "30C"
}
}
My code is as follows.
const express = require('express');
const router = express.Router();
const bodyParser = require('body-parser');
const request = require('request');
const app = express();
const apiKey = 'c6068c4018def9330b01366aed03b08e';
app.use(express.static('public'));
app.use(bodyParser.json());
router.post('/getWeather', function (req, res) {
let cities = req.body.cities;
let weatherJson = [];
for(let i=0; i<cities.length; i++)
{
let city = cities[i];
let url = `http://api.weatherstack.com/current?access_key=${apiKey}&query=${city}`;
request(url, function (response, body) {
if (response) {
return res.json({ error: response });
}
let weather = JSON.parse(body.body);
if (weather.current == undefined) {
return res.json({ error: "somethin went wrong!" });
}
let weatherText = `${weather.current.temperature}C`;
weatherJson.push({ [city] : weatherText });
if(weatherJson.length == cities.length) {
console.log("here");
res.json({"weather": weatherJson});
}
});
}
});
app.use('/', router);
app.listen(3000, function () {
console.log('Example app listening on port 3000!')
});
I have tried adding as hashmap, adding in array format then using stringify at the response point, but nothing seems to work. I just want to convert the format of the response to the desirable one with as minimalistic change in the code as possible. Please help.
You have a few issues, first off you're storing weatherJson (response) as an array when you say you want it to be a map.
here's how I would implement this:
router.post("/getWeather", async function (req, res) {
let cities = req.body.cities;
let weatherJson = {};
for (let i = 0; i < cities.length; i++) {
let city = cities[i];
let url = `http://api.weatherstack.com/current?access_key=${apiKey}&query=${city}`;
try {
const response = await fetch(url);
let weather = JSON.parse(response.body);
if (weather.current == undefined) {
return res.json({ error: "somethin went wrong!" });
}
let weatherText = `${weather.current.temperature}C`;
weatherJson[city] = weatherText;
} catch (err) {
return res.json({ error: err });
}
}
res.json({ weather: weatherJson });
});
You should use node-fetch instead of request which is obsolete. It does the same thing but much cleaner with promises instead of callbacks.
try creating an object instead of an array.
const express = require('express');
const router = express.Router();
const bodyParser = require('body-parser');
const request = require('request');
const app = express();
const apiKey = 'c6068c4018def9330b01366aed03b08e';
app.use(express.static('public'));
app.use(bodyParser.json());
router.post('/getWeather', function (req, res) {
let cities = req.body.cities;
let weatherJson = {};
for(let i=0; i<cities.length; i++)
{
let city = cities[i];
let url = `http://api.weatherstack.com/current?access_key=${apiKey}&query=${city}`;
request(url, function (response, body) {
if (response) {
return res.json({ error: response });
}
let weather = JSON.parse(body.body);
if (weather.current == undefined) {
return res.json({ error: "somethin went wrong!" });
}
let weatherText = `${weather.current.temperature}C`;
weatherJson[city]=weatherText;
if(Object.keys(weatherJson).length == cities.length) {
console.log("here");
res.json({"weather": weatherJson});
}
});
}
});
app.use('/', router);
app.listen(3000, function () {
console.log('Example app listening on port 3000!')
});

I got the problem on the guildMemberAdd event on Discord.js v13.8.0

I got the problem on the guildMemberAdd event. When the event run, I got the error.
This is the console log
Here's my code (index.js):
const { Client, Intents, Collection } = require('discord.js');
const express = require('express');
const app = express();
const fs = require('fs');
const client = new Client({ intents: 32767 });
app.get('/', (req, res) => {
res.send('Hello Express app!');
});
app.listen(3000, () => {
console.log('server started');
});
//--------------------Discord Bot Code below -----------
client.commands = new Collection();
client.cooldowns = new Collection();
['eventsHandler', 'commandsHandler'].forEach(handler => {
require(`./Handlers/${handler}`)(client);
})
client.login(process.env['TOKEN']); //Login With Discord Token
And guildMemberAdd.js
module.exports = {
name: "guildMemberAdd",
execute(member) {
try {
console.log(member.guild.name); //<--- The problem's here
} catch (ex) {
console.error(ex);
};
};
};
Please help me. :((
Here's my event handler
const { readdirSync } = require('fs')
module.exports = (client) => {
const eventFolders = readdirSync(`./Events`)
for (const folder of eventFolders) {
const eventFiles = readdirSync(`./Events/${folder}`).filter(files => files.endsWith(".js"))
for (const file of eventFiles) {
const event = require(`../Events/${folder}/${file}`)
if (event.once) {
client.once(event.name, (...args) => event.execute(...args, client))
} else {
client.on(event.name, (...args) => event.execute(...args, client))
}
}
}
}
This is not how you fire the guildMemberAdd event.
it's a client parameter, so you need to do this
client.on('guildMemberAdd', async (member) => {
// Your code here
});
Read the docs

Error: connect ECONNREFUSED 127.0.0.1:5000

I´ve the file cases.js to create the route I want:
const express = require("express");
const { requireSignin } = require("../controllers/auth");
const { getCases } = require("../controllers/cases");
const { scrapingData } = require("../scrapingData");
const router = express.Router();
router.get("/cases", requireSignin, scrapingData, getCases);
module.exports = router;
requireSignin from controllers/auth looks like this:
exports.requireSignin = expressJwt({
secret: process.env.JWT_SECRET,
userProperty: "auth",
});
scrapingData as middleware I have:
const updateMongoRecords = async () => {
mongoose.Promise = global.Promise;
mongoose.set("debug", true);
Case.deleteMany({}, (err, result) => {
if (err) {
console.log(err);
} else {
console.log("Successfully deleted all records");
}
});
const dataPath = Path.join(__dirname, "files", "covid-data.csv");
try {
let headers = Object.keys(Case.schema.paths).filter(
(k) => ["_id", "__v"].indexOf(k) === -1
);
await new Promise((resolve, reject) => {
let buffer = [],
counter = 0;
let stream = fs
.createReadStream(dataPath)
.pipe(csv())
.on("error", reject)
.on("data", async (doc) => {
stream.pause();
buffer.push(doc);
counter++;
// log(doc);
try {
if (counter > 10000) {
await Case.insertMany(buffer);
buffer = [];
counter = 0;
}
} catch (e) {
stream.destroy(e);
}
stream.resume();
})
.on("end", async () => {
try {
if (counter > 0) {
await Case.insertMany(buffer);
buffer = [];
counter = 0;
resolve();
}
} catch (e) {
stream.destroy(e);
}
});
});
} catch (e) {
console.error(e);
} finally {
process.exit();
}
};
exports.scrapingData = async (req, res, next) => {
const url = "https://covid.ourworldindata.org/data/owid-covid-data.csv";
const path = Path.resolve(__dirname, "files", "covid-data.csv");
const response = await Axios({
method: "GET",
url: url,
responseType: "stream",
});
response.data.pipe(fs.createWriteStream(path));
return new Promise((resolve, reject) => {
response.data.on("end", () => {
resolve(updateMongoRecords());
next();
});
response.data.on("error", (err) => {
reject(err);
});
});
};
And getCases.js inside controllers/cases I have:
const Case = require("../models/case");
exports.getCases = async (req, res) => {
const cases = await Case.find().then((cases) => res.json(cases));
};
With this code I am able to fetch in the route /cases all the cases in the client side (like postman) and it shows all of them. But the problem is that I can´t make any other requests (like signing out, which works fine if I don´t make the get request for the cases like before) afterwards because client (postman) gives the error: GET http://localhost:5000/signout
Error: connect ECONNREFUSED 127.0.0.1:5000
in case you want to see the code for signout is like this:
const express = require("express");
const { signup, signin, signout } = require("../controllers/auth");
const router = express.Router();
router.post("/signup", userSignupValidator, signup);
router.post("/signin", userSigninValidator, signin);
router.get("/signout", signout);
inside controllers/auth.js:
exports.signout = (req, res) => {
res.clearCookie("t");
return res.json({ message: "Signout successfully done" });
};
Any help on this??

Why promise.resolve wait forever in this case?

I am a nodejs's newbie. I'm testing a promise and have an issue.
Here's my issue.
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.json());
app.get('/', async function(req,res){
console.log(222);
res.send("Hello!!!");
let check;
try {
console.log(3333);
check = await test();
console.log(4444);
} catch (err) {
console.log("Error : ", err);
}
console.log(111, check);
});
function test () {
return new Promise (resolve => {
console.log(5555);
app.get('/test', function(req, res) {
count = count + 1;
res.send(count.toString());
resolve("hahahaha");
})
})
}
app.listen(9000, function(){
console.log("hehehehe");
});
In a get 'http://localhost:9000' callback, I wait for 'http://localhost:9000/test' result to do something. The thing is, it's working fine for the first time. But since the 2nd, the promise.resolve() function doesn't work.
Here is my first time log:
hehehehe
222
3333
5555
4444
111 'hahahaha'
And here is my second time log :
222
3333
5555
the promise.resovle() doesn't work. It's waiting forever and I don't understand.
EDIT : Here is the solution for using EventEmitter to do signup and smsVerifyCode after modified by the help of Mr. #Aritra Chakraborty
var express = require('express');
var userControler = require('../Controler/user');
var router = express.Router();
var utils = require('../Helper/Utils');
var user_model = require('../Models/user');
const TIMEOUT_VERIFY = 300000;
const CODE_EXPIRED = 0;
const CODE_VALID = 1;
const CODE_INVALID = 2;
const CONTACT_EXISTED = 3;
const DATABASE_ABUSED = 4;
const events = require('events');
const emitter = new events.EventEmitter();
function timeout_verify_sms_emitter (time) {
setTimeout(() => {
emitter.emit('timeout_sms');
}, time);
}
function verify_code(codeGen) {
return new Promise((resolve, reject)=>{
emitter.on("verifySMS", (data)=>{
if (data === codeGen) {
resolve(CODE_VALID);
}
else {
resolve(CODE_INVALID);
}
})
emitter.on('timeout_sms', () =>{
resolve(CODE_EXPIRED);
});
})
}
router.get('/',function(req,res){
res.send("Welcome to the Earth!!!");
})
router.post('/signup', async function(req,res){
let verifyCode;
let checkContact;
let codeGen = utils.generateCode();
try {
checkContact = await user_model.checkContact(userData.contact);
if (checkContact === true) {
res.send(CONTACT_EXISTED);
}
else {
//call send sms to contact function here
//exam : sendSMS(contact)
//
timeout_verify_sms_emitter(TIMEOUT_VERIFY);
verifyCode = await verify_code(codeGen);
}
}
catch (err) {
console.log("Error : ", err);
}
if (verifyCode === CODE_EXPIRED) {
res.send(CODE_EXPIRED);
}
else if (verifyCode === CODE_VALID) {
var result = userControler.processUserData(req.body);
if (result) {
res.send(CODE_VALID);
}
else {
res.send(DATABASE_ABUSED);
}
}
else {
res.send (CODE_INVALID);
}
})
router.post('/signup/verifySMS', function(req, res){
emitter.emit("verifySMS", req.body.smsCode);
})
module.exports = router;
According to the above code:
Whenever you do a get request to / you are CREATING a /test path.
So, the first time it works because /test path has one handler.
Second or more time it doesn't works because,
The /test route has multiple handler now.
How express works is, routes get executed according to their declaration time. (Think middlewares)
Now, Second time the /test will have 2 handlers. And when you hit /test the first handler runs. And as this is not a middlware it doesn't go to the next handler. Now, the first handler has a different resolve function then the second one. So the second resolve function doesn't run at all.(Think closure)
For what are you trying to do most web implementations use long polling. Because if you wait too long for the second route it will throw a timeout error. Means you periodically hit an api to get the status of something. Means you create 3 routes.
A main route, like /signup
A second route like /sendsms
A third route where you send a particual identifier and it returns some positve/negative value. like /sendsms/check, where you might pass the phone number.
Otherwise if you don't care about timeouts you can use EventEmitter inside the /test route.
EDIT1:
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.json());
const events = require('events');
const emitter = new events.EventEmitter();
let count = 0;
app.get('/', async function (req, res) {
console.log(222);
res.send("Hello!!!");
let check;
try {
console.log(3333);
check = await test();
console.log(4444);
}
catch (err) {
console.log("Error : ", err);
}
console.log(111, check);
});
app.get('/test', function (req, res) {
count = count + 1;
emitter.emit("test",count.toString());
res.send(count.toString());
})
function test(){
return new Promise((res)=>{
emitter.on("test", (data)=>{
res(data);
})
})
}
app.listen(9000, function () {
console.log("hehehehe");
});
EDIT2:
Regarding the solution, you need to handle the timeout differently. Let's say your timeout is 3sec. And the SMS route took 100sec to get a response or maybe it didn't even got a response. Then your function will be stuck there.
function test(sendSMSTime) {
return new Promise((res, rej) => {
emitter.on("test", (data) => {
.
.
res(data);
})
emitter.on('timeout', rej);//On timeout it will run.
})
}
function timeoutEmitter(timeout) {
setTimeout(() => {
emitter.emit('timeout');
}, timeout)
}
app.post('/signup', async function (req, res) {
try {
timeoutEmitter(3000);
.
.
}catch{
}
});

Resources