Storing API response in session - javascript

On POST of a page I'm trying to GET information from an API, return the output and store the results so it can be used across all pages. The method in which the API is called isn't the best but it's just for proof of concept rather than production quality. So here is the code at the moment:
router.post('/page-one/', function (req, res) {
var options = {
'method': 'GET',
'url': 'https://api.information.service.com/company/<value>',
'headers': {
'Authorization': 'Basic <key>'
}
}
request(options, function (error, response) {
if (error) throw new Error(error)
console.log(response.body)
})
res.redirect('/page-two/')
})
So this works fine, the console returns the right information. How would I then take this and use it across all pages? Say on page 2 my get is:
router.get('/page-two/', function (req, res) {
res.render('/page-two/', {
})
})
I'm using Express, Express Session, Express Writer and Nunjucks.

Related

Cannot read POST response body from external api in firebase cloud functions

I have a cloud function which makes an http POST request to the LinkedIn API in order to retrieve an access token. The problem is that I cannot read the body of the response, it's always undefined.
Here's the code
exports.linkedinToken = functions.https.onRequest((req, res) => {
let url = "https://linkedin.com/oauth/v2/accessToken?...REQUIRED_PARAMS...";
request.post(url, {json: true}, (err, response, body) => {
if (!!err) { // this is never happening
console.log(err);
throw err;
} else {
console.log(response.body); // this is always undefined
console.log(body); // this is always undefined
}
});
If I try the same request with Postman or curl it works perfectly, and I cannot really understand why.
Before this request, I made another GET request to the linkedin API and it works normally. Maybe there's a problem with POST requests.
I think you are missing headers.
var request = require('request');
request.post({
headers: {
'content-type' : 'application/x-www-form-urlencoded',
'cache-control' : 'no-cache'
},
url: url
}, function(error, response, body){
console.log(body);
});

Redirect all requests if condition satisfied using middleware

I have an instance of expressjs server running that serves an SPA.
My API lives on another server so I need to bounce my API requests.
I want to create a middleware that redirects all those requests to another host if it meets a certain condition.
The requests that are gonna be handled are the ones with target: API in the request headers
so far this is how my middleware looks like and I am able to capture selected request which meets the condition:
function apiHelmet(req, res, next) {
if (req.get('target') === 'API') {
/*
find a way to redirect requests of all methods and pipe result to response
*/
return res.send(response_from_external_api)
}
return next()
}
my setup:
app.use(apiHelmet)
app.get('*', renderSPA)
example post request:
axios({
method: 'POST',
data: { id: 123, first_name: 'john', last_name: 'doe' },
url: '/users',
headers: {
target: 'API'
}
} ).then(result=>console.log(result))
Try this, Call another External API using request module and pipe External API response directly to Your server response.
var request = require('request');
app.use(apiHelmet)
app.get('*', function (req, res, next) {
req.pipe(request('SOME URL').on('error', function (err) {
return res.status(400).send(err)
})).pipe(res);
});
You can do this easily using following code.
function apiHelmet(req, res, next) {
if (req.get('target') === 'API') {
return res.send('caught ya')
req.post({url: 'http://end-point', headers: req.headers, body: req.body});
processRequest(req);
res.setHeader('Content-Type', 'application/json');
res.send('Req OK');
}
return next()
}
For more details see.

MYSQL + Node.JS Post Request Confusion

I am very new to networking and I have this code which, when I use a REST API like Postman, does exactly what I want it to do:
router.post('/', function(req,res,next){
var reqObj = req.body;
console.log(reqObj);
req.getConnection(function(err, conn){
if(err)
{
console.error('SQL Connection error: ', err);
return next(err);
}
else
{
var query = conn.query("INSERT INTO coordinates (id,lat,lon) VALUES(3,2,1);");
if(err)
{
console.error('SQL error: ', err);
return next(err);
}
res.json("Coordinates sent.");
}
})
} );
That is, it sends the query request to the MYSQL database. My question is, how do I do this without using Postman to send the POST request?
Thank you.
You can't unless you make a post request from within your application or something. If you don't intend on sending data, you can just make it a GET request by changing
router.post('/', function(req,res,next){
to
router.get('/', function(req,res,next){
Then you can just go to the relevant URL from your browser. If you're using chrome and you just wanna see the JSON data, I'd also recommend installing the JSONView chrome extension.
EDIT
Here's the example request using request-promise
var request = require('request-promise');
var objectData = {
name: 'Bruce',
alias: 'Batman'
};
var options = {
method: 'POST',
uri: 'http://your.api/endpoint/',
body: objectData,
json: true // Automatically stringifies the body to JSON
};
request(options).then(function(response){
// handle success response
}, function(error){
// handle error response
})

404 Error with 'get' fetch request from locally hosted server

I am building a simple blog using the principles I learned here (CRUD app with Express and MongoDB). In order to edit previously published posts, I want to populate a text field with the contents of a blog post whose title is selected from a drop-down menu. That way I can easily make my changes and submit them.
I have written a basic 'put' fetch request that does absolutely nothing except report an error if something goes wrong:
fetch('articles', {method: 'put'})
.then(
function(response) {
if (response.status !== 200) {
console.log('Looks like there was a problem. Status Code: ' + response.status);
return;
}
// Examine the text in the response
response.json().then(function(data) {
console.log(data);
});
}
)
.catch(function(err) {
console.log('Fetch Error :-S', err);
});
Nothing goes wrong here, so console.log(data) is executed:
However, when I change 'put' to 'get' (and make no other changes), I get a 404 error:
How can it be that the 'get' fetch request causes a 404 error, but the 'put' request doesn't? I am hosting this app locally, so I'm running it from localhost:3000. The 'get', 'post', and 'put' operations in my server code look like this:
app.get('/', function (req, res) {
db.collection('articles').find().toArray(function (err, result) {
if (err) return console.log(err);
res.render('index.ejs', {articles: result});
});
});
app.post('/articles', function (req, res) {
db.collection('articles').save(req.body, function (err, result) {
if (err) return console.log(err);
console.log('saved to database');
res.redirect('/');
});
});
app.put('/articles', function (req, res) {
db.collection('articles')
.findOneAndUpdate({title: 'test title'}, {
$set: {
title: req.body.title,
body: req.body.body
}
}, {
sort: {_id: -1},
upsert: true
}, function (err, result) {
if (err) return res.send(err);
res.send(result);
});
});
I would like to eliminate this 404 error so I can proceed with the ultimate reason I'm using the 'get' request: to populate a text field with the contents of a previously published blog entry. After I've made my edits, I plan to use the 'put' request to finalize the changes in MongoDB.
Please let me know whether you need any additional information. Your advice is much appreciated!
You do not have a GET /articles route; you do have a GET / route, however.
If you want GET /articles to work, you should change the first argument to app.get to '/articles'.

Call a hapi route from another route

I am pretty new to HapiJS. I am building a service where I have two routes /route1 and /route2 both are using the plugin architecture. I have registered both as plugins on my manifest file.
I want to call /route1 from /route2 so /route2 depends on the payload reply from /route1. I've been looking at putting the logic of /route2 on /route1 on the pre-handler but I want to keep them separately.
Don't know how to call a registered plugin from another the thing is that both plugins (routes) are making networks requests. Thanks for reading.
Thanks.
As you specify that you don't want to use a shared handler/route prerequisite (which would be my first choice), you could make an actual request using a http client (Wreck, request, http or the like).
Another, more efficient way that doesn't involve actually making a network request is to use hapi's built-in server.inject() method provided by Shot. This will inject a request into your server and get the response, which you can use. Here's an example:
var Hapi = require('hapi');
var server = new Hapi.Server();
server.connection({ port: 4000 });
var plugin1 = function (server, options, next) {
server.route({
method: 'GET',
path: '/route1',
handler: function (request, reply) {
reply('Hello');
}
});
next();
};
plugin1.attributes = { name: 'plugin1' };
var plugin2 = function (server, options, next) {
server.route({
method: 'GET',
path: '/route2',
handler: function (request, reply) {
server.inject('/route1', function (res) {
reply(res.payload + ' World!');
});
}
});
next();
};
plugin2.attributes = { name: 'plugin2' };
server.register([plugin1, plugin2], function (err) {
if (err) throw err;
server.start(function (err) {
if (err) throw err;
console.log('Started');
});
});
Note that the fact the routes are in plugins here is irrelevant. I've merely included it so it's close to your situation.
Shot and server.inject() are primarily used for testing but there are legitimate runtime uses like this too.
If you make a request to /route2, this will invoke /route1 handler and get the payload:
$ curl localhost:4000/route2
Hello World!

Categories