Using request within routes node / express - node.js

I'm playing around with using nodejs as a custom front end for drupal and i'm trying to come up with a way to match the backend menu system, blocks and views with the routing in express.
example route
module.exports = {
'/work': function(req, res){
//get view json for this page
request('http://site.api/casestudies', function(err, response, body){
views_body = JSON.parse(body);
//get node id from alias
request('http://site.api/alias-to-nid' + req.url, function(err, response, body){
body = JSON.parse(body);
var reqUrl = 'http://site.api/rest/api/' + body.path;
request(reqUrl, function(err, response, body){
body = JSON.parse(body);
//get the data we need
var node_title = body.title,
node_body = body.body.und[0].safe_value,
pageclass = 'not-front section-work';
res.render('work', {title: node_title, class:pageclass, node_title:node_title, node_body:node_body, views_body:views_body});
});
});
});
}
}
So, i hit /work and grab the json for the casestudies view that should exist on that page, then i lookup the node id from the /work alias using another request and finally use the node id in yet another nested request call to grab the rest of the json for the page before finally sending it on the the template.
Now - I have a feeling that this is a terrible way to go about this. What should I be doing instead!?

Related

How to send multiple request in nodejs using ejs template

I'm getting data through a single request. But here I am trying to send multiple HTTP requests. Here I just struck unable to get data and how to pass data in view page i.e, in EJS
router.get('/specials',function(req,res,next){
var callbackThree = function(error, resp, body) {
var data = JSON.parse(body);
res.render("specials",{ data: data});
}
var callbackTwo = function(error, resp, body) {
request("https://siteblabla.com/wsmenu/sub_menu_list/789/", callBackThree);
}
var callbackOne = function(error, resp, body) {
request("https://siteblabla.com/wsspecials/specials_list/123/", callBackTwo);
}
// request("api.com/users", callBackOne);
});
You need to use Promises and there is a great npm package called ejs-promise which you can make use of in your case.
You can download it at the below URL,
https://www.npmjs.com/package/ejs-promise
Hope this helps!

Get data from webpage with cheerio

I am trying to get the API response time from a website with cheerio. I have to wait first though for the site to fetch the time, though I am not sure how exactly to do that. Here is what I have tried. At the moment it does not work because it doesnt wait for the website to fetch the time.
request.get("site", function (err, res, body) {
if (!err) {
var $ = cheerio.load(body);
$('.metrics-container').filter(function(){
var data = $(this);
var response_time_api = data.children().children().children()[1].children;
console.log(response_time_api)
});
}
});
here is the image from the source am fetching

Request API data into Express view

Newbie here. I'm trying to send data I received from making making an API call (when the user requests the zoopla page) into an index.ejs view. I'm trying to pass the graph_url by passing it in the res.render.
The graph_url logs correctly, so the API call is coming back, however I get the following error in my terminal:
ReferenceError: graph_url is not defined
Here is my index.js request for the page:
app.get('/zoopla', function(req, res){
request(zoopla, function(err, res, data){
var data = JSON.parse(data);
var graph_url = data.area_values_url
console.log(graph_url);
});
res.render('index', { title : "zoopla", graph : graph_url});
});
graph_url is not defined because is out of the local scope, and also you are trying to render the page before the previous async request() call complete.
try with:
app.get('/zoopla', function(req, res){
request(zoopla, function(err, res, data){
if (err) {
/* handle errors */
}
var data = JSON.parse(data);
var graph_url = data.area_values_url
console.log(graph_url);
res.render('index', { title : "zoopla", graph : graph_url});
});
});

Express calling an api inside of a post request

I've hit a wall here, and can't really find a clear way of achieving this. I want to create a new video to add to my database. I get all the information from the view form, but a couple of the keys have to come from an api. So here's a basic example of what I have and need. What's a good way of achieving this?
router.post("/new", function(req, res){
var videoId = req.body.videoId;
var views = req.body.views;
//call the api with the video Id here somehow, and get title key for the video object below
//"www.api.com/"+videoId"
var video = {
title: title, //title from received from the api call
views: views
}
video.create(video, function(err, video){
//etc
})
});
You can use the http module built-in node to request the information from the API, otherwise request, which is probably more convenient to use.
Your code would then look like:
var request = require('request')
router.post("/new", function(req, res){
var videoId = req.body.videoId;
var views = req.body.views;
//call the api with the video Id here somehow, and get title key for the video object below
request.get('www.api.com/' + videoId, function(err, res) {
var videoData = {
title: res.title, //title from received from the api call
views: res.views
}
video.create(videoData, function(err, video){
//etc
})
})
});

How do I access the instagram API with Express JS and Jade?

I am having some trouble getting information for Instagram's API and the sending it to Jade to be rendered on the front end.
app.route("/api")
.get(function(req, res){
var url = "https://api.instagram.com/v1/users/1234/media/recent/?client_id=XXXX";
request(url, function(err, res, data){
console.log(JSON.parse(data));
// does this go here
res.render('show', {media : data});
});
// or here?
res.render('show', {media : data});
});
I am trying to collect 10 images from this API path and send them to Jade. I am getting a parsed response in my terminal of several entries. I am having a hard time figuring out how to send multiple responses to a Jade file, then having the Jade file loop through them.
I do know that the user ID and client ID in the url variable are not correct. If you have any alternate method to using request(), I am open to that as well.
So I am answering my own question on this one. The rendering has to be inside of the request() function. The issue was in my callbacks. The issue was that I had "res" as a response for my .get and my request() callback. When I changed the "res" in the request() function to "response" I was not getting any issues anymore. Jade file is below as well
app.route("/api2")
.get(function(req, res){
var url = "https://api.instagram.com/v1/users/1234/media/recent/?client_id=XXXX";
request(url, function(err, response, body){
var dataGram = JSON.parse(body);
res.render('show', dataGram);
});
});
Jade File:
each thing in data
h1 id : #{thing.id}
img(src="#{thing.images.thumbnail.url}")
a(href="#{thing.link}" target="_blank") link
h3 filter : #{thing.filter}

Resources