handling session variables inside http.request in express - node.js

Hi. When i print the req.session.mySessValue in UI , the value is empty. I think the assigning of req.session.mySessValue = dt.myValue; (express-session) is not proper. could anyone help me on this. Thanks in advance.my express code is
router.get('/', function(req, res, next) {
if(!req.xx) {
return res.redirect('/firstView');
}
var options = {
.......
};
var call = http.request(options, function(resp) {
resp.on('data', function(dt) {
var jsondata = JSON.parse(dt);
req.session.mySessValue = dt.myValue;
});
});
call.end();
call.on('error', function(e) {
console.log("error" +e.message)
});
var v = {
title: 'sample',
req : req
}
res.render('myview', v);
});

Related

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!')
});

how to get the api result from middleware to routes

I just wanted to get the result from the API in the middle ware that apply to routes. i am using express js the res.locals.wallet doesn't have a value
var request = require('request');
module.exports = function(req, res, next) {
if(req.session.active){
res.locals.active = req.session.active;
res.locals.email = req.session.email;
// res.locals.wallet = req.session.wallet;
res.locals.admin = req.session.admin;
res.locals.cart = req.session.cart;
res.locals.partner = req.session.partner;
var data = {
user_id :req.session.user_id,
}
request.post({
url : 'https://api.sample.com/frontend/sample',
form : data,
}, function (error, response, body) {
var bodyJson = JSON.parse(body);
console.log(bodyJson);
res.locals.wallet = req.session.wallet; <----- HERES THE PROBLEM
next();
});
} else {
res.redirect("/login");
}
next();
};
You call next immediate in your middleware, now res.locals.wallet value is undefined.
Just call next when you finish the job (call api).
var request = require('request');
module.exports = function(req, res, next) {
if(req.session.active){
res.locals.active = req.session.active;
res.locals.email = req.session.email;
// res.locals.wallet = req.session.wallet;
res.locals.admin = req.session.admin;
res.locals.cart = req.session.cart;
res.locals.partner = req.session.partner;
var data = {
user_id :req.session.user_id,
}
request.post({
url : 'https://api.sample.com/frontend/sample',
form : data,
}, function (error, response, body) {
var bodyJson = JSON.parse(body);
console.log(bodyJson);
res.locals.wallet = req.session.wallet; <----- HERES THE PROBLEM
next();
});
} else {
res.redirect("/login");
}
// next(); <----------------- remove this line
};

Socket IO -- socket.emit firing every event twice

socket.js:
var state = {
io: null
}
exports.init = function(io) {
state.io = io;
}
exports.get = function() {
return state.io;
}
exports.emit = function(message, data) {
console.log("emitting")
state.io.emit(message, data);
}
exports.onConnection = function(callback) {
state.io.once('connection', function (socket) {
callback(socket);
});
}
tags.js:
router.get('/', function (req, res) {
var DeviceIdentifier = 'WILL'
var NDefRecord = 'FROM_WILL'
req.headers['x-name'] = DeviceIdentifier
req.headers['x-content'] = NDefRecord
console.log("tags.js: GET");
socket.emit("tag:scan", {name: "000000000a0d9439", content: "adsf});
})
server.js
var io = require('socket.io')(server);
var socket = require('./socket');
socket.init(io);
socket.onConnection(function (data) {
console.log("Got Connection");
console.log(data);
});
No matter how I am doing it, the socket.emit function is called twice and data is getting stored twice as well.
I've tried looking up many examples and the problem still seems like it is persisting
Any help would be appreciated.
Thanks!
just add res.send . you are not sending any response to the browser so he try to refresh after x seconds
router.get('/', function (req, res) {
var DeviceIdentifier = 'WILL'
var NDefRecord = 'FROM_WILL'
req.headers['x-name'] = DeviceIdentifier
req.headers['x-content'] = NDefRecord
console.log("tags.js: GET");
socket.emit("tag:scan", {name: "000000000a0d9439", content: "adsf});
res.send('ok');
})

Can I use 'res' object in koa?

I am pretty new to koa. My old code is in express, like:
//GET
exports.readMessages = function(req, res){
var result;
...
res.json({
result: result
});
};
//GET
exports.preAddMessage = function(req, res){
var valueA;
var valueB;
...
res.json({
valueA: valueA,
valueB: valueB
});
};
// POST
exports.addMessage = function (req, res) {
data.messages.push(req.body);
...
res.json(resultValue);
};
And I want to change it to code in koa, like:
//GET
exports.readMessages = function* () {
...
};
//GET
exports.preAddMessage = function* () {
...
};
//POST
exports.addMessage = function* () {
...
};
How to do it? The question may seem silly, but it matters to me, thanks!
//GET
exports.readMessages = function* () {
this.body = {result: result};
};
//GET
exports.preAddMessage = function* () {
this.body = {
valueA: valueA,
valueB: valueB
};
};
//POST
exports.addMessage = function* () {
data.messages.push(this.request.body); // you might need a body parser middleware if the request is json
this.body = resultValue;
};

Hijack response before sent to client

I have follow codes to be used as middlewares
module.exports=function(callback) {
callbacks.push(callback);
return function(req,res,next) {
if (!res.hijacked) {
res.hijacked=true;
} else {
return next();
}
var send=res.send;
res.send=function(data) {
var body=data instanceof Buffer ? data.toString() : data;
var requests=[];
requests.push(function(next) {
callbacks[0](req,res)(body,doneWrapper(body,next));
});
for (var i=1;i<callbacks.length;i++) {
var hijackCallback=callbacks[i];
requests.push(function(result,next) {
hijackCallback(req,res)(result,doneWrapper(result,next));
});
}
var that=this;
async.waterfall(requests,function(err,result) {
send.call(that,result);
requests=null;
body=null;
that=null;
});
};
next();
};
};
An example of usage is as following:
module.exports=function() {
return hijack(function() {
return function(result,done) {
var json={};
try {
json=JSON.parse(result);
} catch(e) {
return done();
}
if (!_.isArray(json)) {
return done();
}
var sorted=_(json).sortBy(function(item) {
if (_.isObject(item.information)) {
return item.information.rangeIndex1 || 999;
} else {
return 1001;
}
});
done(sorted);
}
});
};
It worked fine initially as middlewares in routes.
However,When i try to make it as app.use(hijackMiddleware()). Something went wrong, I got this Can't set headers after they are sent error.
There is no problem when used as middlewares in routes,though.
Have you consider using express-interceptor? Is really easy to use:
var express = require('express');
var cheerio = require('cheerio');
var interceptor = require('express-interceptor');
var app = express();
var finalParagraphInterceptor = interceptor(function(req, res){
return {
// Only HTML responses will be intercepted
isInterceptable: function(){
return /text\/html/.test(res.get('Content-Type'));
},
// Appends a paragraph at the end of the response body
intercept: function(body, send) {
var $document = cheerio.load(body);
$document('body').append('<p>From interceptor!</p>');
send($document.html());
}
};
})
// Add the interceptor middleware
app.use(finalParagraphInterceptor);
app.use(express.static(__dirname + '/public/'));
app.listen(3000);

Resources