Node Script have to call a URL , and get the response and use the some variable of the response to call the next url. is it possible?
in below example, i'm using token in other scripts.
var http = require('http');
var options = {
host: 'url' ,
path: '/path',
method: 'POST'
};
var req = http.request(options, function(res) {
token="hi"; // to be populated by res
});
req.end();
exports.token = token
I think you're trying to export token before it exists. When you assign token = "hi", that happens after the http request finishes and you get the response. What you want to do instead is export a function with a callback which returns your data from the url.
var http = require('http');
var options = {
host: 'url' ,
path: '/path',
method: 'POST'
};
exports.getToken = function (callback) {
http.request(options, function(res) {
callback(res);
});
};
Then in your other module, you would have to call the getToken function passing it a callback function.
//I assume the above file is called tokenFinder.js
var tokenFinder = require('./tokenFinder');
var token;
tokenFinder.getToken(function (data) {
token = data;
});
Related
Im trying to achieve the following things in application created from scratch using nodeJs.
Read the list of users from a file in my solution.
Get all the public repositories of those users.
Below is my code
const express = require("express");
const app = express();
const request = require('request');
const fs = require("fs");
var path = require("path");
var rootDir = process.argv.length > 2 ? process.argv[2] : process.cwd();
var filePath = path.join(rootDir, "userList.txt");
const https = require('https');
app.listen(3002, function () {
console.log("Server running on port 3002...");
});
app.get("/getUserRepository", function (req, res, next) {
fs.readFile("myFilePath/myFile.txt", {encoding: "UTF8"}, function (err, userListObject) {
getDataObject(userListObject);
});
});
function getDataObject(userList) {
var userRepoData = [];
var userListArray = userList.split(",");
userListArray.forEach(function (userListObject) {
https.request("https://api.github.com/users/" + userListObject + "/repos", function (res) {
res.setEncoding('utf8');
res.on('data', function (data) {
userRepoData.push(JSON.parse(data));
});
}).end();
});
}
The challenge im facing is, when im making a separate call to get the repo of each user, im getting exception
"Request forbidden by administrative rules. Please make sure your request has a User-Agent header (http://developer.github.com/v3/#user-agent-required)."
Im not finding any example / approach as to where i can add the user-agent.
Also one more thing that i want to know is, where this is the best approach to achieve what i want.
Try this
userListArray.forEach(function (userListObject) {
var options = {
url: "https://api.github.com/users/" + userListObject + "/repos",
headers: {
'User-Agent': 'my node app'
}
};
https.request(options, function (res) {
res.setEncoding('utf8');
res.on('data', function (data) {
userRepoData.push(JSON.parse(data));
});
}).end();
});
As the error says you are missing a header User-Agent. Refactor your code like this
function getDataObject(userList) {
let userRepoData = [];
let userListArray = userList.split(",");
let options = {
host: 'api.github.com',
path: '/users/' + username + '/repos',
method: 'GET',
headers: {'user-agent': 'node.js'}
};
userListArray.forEach(function (userListObject) {
https.request(options, function (res) {
res.setEncoding('utf8');
res.on('data', function (data) {
userRepoData.push(JSON.parse(data));
});
}).end();
});
}
You can read more about User-Agent here.
Basically you need to pass how are you trying to access github api. If you try with browser it automatically sends the user-agent, similar with postman but once writing a script you need to manually pass the user-agent
//route to search (POST http://localhost:8080/api/search)
apiRoutes.post('/search', function(req, res) {
console.log('search');
var query = req.params;
console.log(query);
options = {
protocol : "https:/",
host: "https://api.themoviedb.org",
path: "/3/search/movie?api_key=35f7a26be584f96e6b93e68dc3b2eabd&language=en-US&page=1&include_adult=false&query="+query,
};
var req = https.request(options, function(res) {
var chunks = [];
res.on("data", function (chunk) {
chunks.push(chunk);
});
res.on("end", function () {
var body = Buffer.concat(chunks);
console.log(body.toString());
});
});
req.write("{}");
req.end();
})
DOES ANYONE KNOW WHERE THE PROBLEM IS?
I'm trying to do a request to do a research to the api the movie db and get the result back
There are some problems with the code. I have tested it and made it to work.
let options = {
host: "api.themoviedb.org",
path: "/3/search/movie?api_key=35f7a26be584f96e6b93e68dc3b2eabd&language=en-US&page=1&include_adult=false&query="+query.data.replace(' ','%20'),
};
first of all since you are using https module you don't need to specify the protocol nor you need to put it in the url. That's how your options variable should be.
Second you are appending the entire query object to the url which is {} instead you should append a string which will be in one of the key of your query object in my case its query.data
Third if there are spaces in the string Eg: Home Alone you to maintain space and avoid the error we replace the string with %20 which is a escaping character.
Forth Try giving a unique name for https request variable and its response variable in the callback function or it will override the route's req res variables cause your code to not work. Notice how I have used route's res function to send the data back and end the response
Also I am getting the data in req.body and you are using req.params however there are no params defined in your routes. Try going through the documentation for more information
Here is the complete code
apiRoutes.post('/search',function (req, res) {
https = require('https');
var query = req.body;
console.log(query.data);
let options = {
host: "api.themoviedb.org",
path: "/3/search/movie?api_key=35f7a26be584f96e6b93e68dc3b2eabd&language=en-US&page=1&include_adult=false&query="+query.data.replace(' ','%20'),
};
var request = https.request(options, function(response) {
var chunks = [];
response.on("data", function (chunk) {
chunks.push(chunk);
});
response.on("end", function () {
var body = Buffer.concat(chunks);
console.log(body.toString());
res.send(body);
res.end()
});
});
request.end();
});
Hope it helps.
I am using npm request module (https://www.npmjs.com/package/request) to post binary content to a servlet. The binary content is received as part of http request, using the npm request module it is then posted to the J2ee server.
Along with the post, I need to pass some custom headers. I am using the below code to do that
var req = require('request');
function upload(request, response) {
var options = {
headers: {
'customheader1': 'val1',
'customheader2': 'val2'
}
};
var target = req.post('http://'+host+':'+port+'/myapp/Upload', options);
request.pipe(target);
target.on('finish', function() {
console.log('Uploaded with headers');
})
}
However, the headers are going as blank to the server. What would be the right way to pass headers using request.post?
As per request Docs (http://github.com/request/request)
var req = require('request');
function upload(request, response) {
var options = {
url: 'http://'+host+':'+port+'/myapp/Upload',
headers: {
'customheader1': 'val1',
'customheader2': 'val2'
}
};
var target = req.post( options, function(err,data){
console.log('uploaded with headers')
})
request.pipe(target);
}
I'm trying to make a chain of promises functions which use HTTP requests in NodeJS with Kraken framework.
My code could work in 90% of cases, but if the distant requested server takes time to respond, the code will return an error with undefined values. So I think Q is a good solution to prevent that.
Here's the situation :
We access to a URL with a "code" parameter -> the route controller takes this param to use it in a HTTP POST request -> the response (a token) is stored in a variable and used in an other HTTP GET request -> the response (multiple JSON objects) is stored in variable too -> all variables are stored in a MongoDB.
If functions are not used in this order, of course it fails.
var Q = require('q');
module.exports = function (router) {
router.get('/', function (req, res) {
var codein = req.param('code');
if(codein){
console.log('Provided code: ' + codein+'\n');
getAccessToken(codein).then(function(token){
console.log('Provided AccessToken: ' + token + '\n');
getUsername(token).then(function(userdata){
console.log('Provided Username: ' + JSON.parse(userdata).username + '\n');
storeData(userdata).then(function(msg){
console.log(msg);
res.redirect('/dashboard/' + JSON.parse(userdata).username);
});
});
});
}
else{
console.log('Access Denied, redirecting...');
res.redirect('/');
}
});
};
This method works, but actually didn't resolve the problem, because sometimes variable are undefined again. I think it's my request functions which aren't well made...
Here's an example of the first function with POST request :
var getAccessToken = function(cod){
var def = Q.defer();
var data = querystring.stringify({
client_id:"1234567890",
client_secret:"******",
grant_type:"authorization_code",
redirect_uri:"http://localhost:8000/r/callback",
code:cod
});
var options = {
host: 'domain.server.com',
port: 443,
path: '/api/oauth2/token',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': Buffer.byteLength(data)
}
};
var response = "";
var req = https.request(options, function(res) {
res.setEncoding('utf8');
res.on('data', function (chunk) {
response += chunk;
});
res.on('end', function(){
var json = JSON.parse(response);
var acto = json.access_token;
def.resolve(acto);
});
});
req.write(data);
req.end();
return def.promise;
};
In this case the acto variable can be undefined... So am I using Q in a wrong way ?
EDIT
To understand my problem, let me show you what can I have in my output console (really rare but happens) :
Provided code: 12345678910
Provided Username: user543210
Instead of :
Provided code: 12345678910
Provided AccessToken: 9876543210
Provided Username: user
I think you need to account for 2 scenarios
Where the Twitch API takes time to respond.
The Twitch response cannot be parsed
The code
res.on('end', function(){
var json = JSON.parse(response);
var acto = json.access_token;
def.resolve(acto);
});
Should be modified as:
try {
var json = JSON.parse(response);
var acto = json.access_token;
//check if acto is undefined
if (acto === undefined) {
def.reject('Some error message');
} else {
def.resolve(acto);
}
} catch (error) {
//since the JSON could not be parse
def.reject(error);
}
I'm unable to get the var data I sent in via a POST method. This should be easy (right?), but I'm clearly missing something (either conceptually or a setting).
At this stage, I simply want to check to see if the server side code will output the data to the console. The array is being stringify-ed correctly, eg. ['one','two','three'] becomes 0=one&1=two&2=three
but I can't pull it out on the server side.
What am I missing?
Client side
var qs = require('querystring')
, http = require('http');
var some_array = ['one','two','three'];
var data = qs.stringify(some_array);
var options = { host: 'localhost',
path: '/search',
port: '3000',
method: 'POST',
headers: { 'content-length': Buffer.byteLength(data),
'Content-Type': 'application/json' }
}
function go_post(data) {
req = http.request(options, function(res) {
// do something with response
});
req.write(data);
req.end();
};
go_post(data);
Server side
var connect = require('connect');
var qs = require('querystring');
var server = connect.createServer();
server.use(function(req,res,next) {
if ( '/search' == req.url && req.method == 'POST' ) {
// quick check to see if data came through
console.log('BODY IS ' + req.data);
} else {
next();
};
});
These objects arent available because they are still in the "raw" request. You have to use a middleware like connect().use(connect.bodyParser()) in order to get them from the request via req.data.