How to save data from JSON to a variable in NodeJS - javascript

I'm new in Node.js, I have a problem.
I would like to save data from JSON object which I have downloaded from github API.
var http = require("http");
var express = require('express');
var app = express();
var github = require('octonode');
var client = github.client();
app.set('port', process.env.PORT || 8000);
var server = app.listen(app.get('port'), function() {
console.log('Express server listening on port ' + server.address().port);
});
app.get('/getUsers', function (req, response) {
response.writeHead(200, {'Content-Type': 'text/json'});
var result;
client.get('/users/angular/repos', {}, function (err, status, body, headers) {
result = response.write(JSON.stringify(body));
console.log(result); //JSON object
return result;
});
console.log(result); //undefined
});
How can I save an data from object to single variable?
(I want to then transform it to an Array and take some useful data).

You will not get result outside of the asynchronous call as it is not yet defined. To get this value either call a method inside the callback of query or use async module and pass it.
app.get('/getUsers', function (req, response) {
response.writeHead(200, {'Content-Type': 'text/json'});
var result;
client.get('/users/angular/repos', {}, function (err, status, body, headers) {
result = response.write(JSON.stringify(body));
console.log(result); //JSON object
doSomeOperationOnResult(result)
});
});
function doSomeOperationOnResult(result){
//Your operating code
}

Related

Parse request in my simple Node Js server

I'm new to Node and am trying to build a simple server in Node using Express. The requests are in the form of say /input00001/1/output00001. What I need to do is to parse this request and if the flag is 1 (middle value), I need to replace the file \home\inputfiles\input00001.txt with file \home\outputfiles\output00001.txt. How is it possible to do that?
Here is my simple server so far. I'm OK with not using the Express and pure NodeJs if that makes things easier.
const express = require('express');
const app = express();
const port = 8000;
app.get('/', (request, response) => {
response.send('Hello from Express!');
request.param
});
app.get('/*', (request, response) => {
response.send('Start!');
var url = request.originalUrl;
});
app.listen(port, (err) => {
if (err) {
return console.log('something bad happened', err);
}
console.log(`server is listening on ${port} for incoming messages`);
});
You should set up a route that expects these items as url parameters and then use those parameters to do what you want. For example if you're url is /input00001/1/output00001 then you could set up a route like this:
app.get('/:input/:flag/:output', (req, res) => {
var params = req.params
var input = params.input //input0001
var flag = params.flag // 1
var output = params.output //output0001
// now do what you need to with input, flag, and output
if(typeof flag!=='undefined' && flag==1){
var file_name_string = '\home\inputfiles\input00001.txt';
var res = file_name_string.replace("input", "output");
}
console.log(input, flag, output)
res.send("done")
})

Redirect image request on NodeJS

Inside my application code, for a specific set of APIs, I'm making a NodeJS request like following, which should return a image as the body. This same request works fine on Postman (and I can see the image).
module.exports = {
getThumbnail: function (thumbnailUrn, env, token, onsuccess){
request({
url: config.baseURL(env) + config.thumbail(thumbnailUrn),
method: "GET",
headers: {
'Authorization': 'Bearer ' + token,
}
}, function (error, response, body) {
// error check removed for simplicity...
onsuccess(body);
});
}
}
The above code run under my own security checks and adds the token header. It works fine (request calls return 200/OK).
Now on my app router I want to respond this as an image, but the output is not being interpreted as an image. Here is what I have:
var dm = require(/*the above code*/);
// express router
var express = require('express');
var router = express.Router();
router.get('/getThumbnail', function (req, res) {
var urn = req.query.urn;
dm.getThumbnail(urn, req.session.env, req.session.oauthcode, function (thumb) {
res.writeHead(200,
{
'Content-Type': 'image/png'
}
);
// at this point, the 'thumb' variable is filled
// but I believe is not properly encoded...
// or maybe the res.end output is missing something...
res.end(thumb, 'binary');
});
});
module.exports = router;
EDIT: as commented by Nodari Lipartiya, this is kind of proxy behaviour ( server(responds with image) -> proxy (node.js/resends to client) -> end user)
I'm not sure what is coming back in thumb, but the following snippet seemed to work for me (bypassing Express for simplicity):
var http = require("http")
var fs = require("fs")
var server = http.createServer(listener)
server.listen(() => {
console.log(server.address().port)
})
var binary = fs.readFileSync("path to local image")
function listener(req, resp) {
resp.writeHead(200,
{
'Content-Type': 'image/png'
}
);
resp.end(new Buffer(binary), "binary")
}
What happens if you wrap it in a Buffer?
If I've understood everything correctly:
I did this
server.js
var fs = require('fs');
var express = require('express');
var app = express();
app.get('/img', function(req, res, next) {
var stream = fs.createReadStream('img.jpeg');
var filename = "img.jpeg";
filename = encodeURIComponent(filename);
res.setHeader('Content-disposition', 'inline; filename="' + filename + '"');
res.setHeader('Content-type', 'image/jpeg');
stream.pipe(res);
});
app.listen(9999, function () {
console.log('Example app listening on port 9999!');
});
proxy.js
var request = require('request');
var express = require('express');
var app = express();
app.get('/img', function(req, res, next) {
console.log('proxy/img');
request({
url: 'http://localhost:9999/img',
method: "GET",
}, function (error, response, body) {
res.end(body, 'binary');
});
});
app.listen(9998, function () {
console.log('Example app listening on port 9998!');
});
req.js
var request = require('request');
request({
url: 'http://localhost:9998/img',
method: "GET",
}, function (error, response, body) {
console.log('body', body);
});
works for me. Please, let me know if you'll need help.

Testing a node.js server in the same process as the test

I am wondering if there is any disadvantage to starting a server in a process and then running tests against that server in the same process.
Obviously there are some performance concerns, but if we are testing accuracy instead of performance, are there any major concerns with code like the following?
var fs = require('fs');
var path = require('path');
var http = require('http');
var supertest = require('supertest');
var assert = require('assert');
describe('#Test - handleXml()*', function() {
var self = this;
var server;
var payload = ''; // stringified XML
var xmlPath = path.resolve('test', 'test_data', 'xml_payloads', 'IVR_OnDemandErrorCode.xml');
before(function(done) {
var config = self.config = require('univ-config')(module, this.test.parent.title, 'config/test-config');
server = createServer().on('listening', function() {
done(null);
});
});
beforeEach(function(done) {
fs.readFile(xmlPath, 'utf8', function(err, content) {
assert(err == null);
payload = content;
done();
});
});
it('should accept request Content-type "text/xml or application/xml"', function(done) {
supertest(server)
.post('/event')
.set('Content-Type', 'application/xml')
.send(payload)
.expect(200, done);
});
it('should transform XML payload into JSON object', function(done) {
supertest(server)
.post('/event')
.set('Content-type', 'application/xml')
.send(payload)
.expect(200)
.end(function(err, res) {
assert(err == null,'Error is not null');
var jsonifiedXml = JSON.parse(res.text);
assert(typeof jsonifiedXml === 'object','jsonifiedXml not an object');
done();
});
});
describe('JSONified XML', function() {
it('should have proper key casing', function(done) {
supertest(server)
.post('/event')
.set('Content-type', 'application/xml')
.send(payload)
.expect(200)
.end(function(err, res) {
assert(err == null);
var payload = JSON.parse(res.text);
payload = payload.events[0].data;
assert(payload.hasOwnProperty('ppv'),'Bad value for ppv');
assert(payload.hasOwnProperty('mac'),'Bad value for mac');
assert(payload.hasOwnProperty('appName'),'Bad value for appName');
assert(payload.hasOwnProperty('divisionId'),'Bad value for divisionId');
assert(payload.hasOwnProperty('callTime'),'Bad value for callTime');
assert(payload.hasOwnProperty('callDate'),'Bad value for callDate');
assert(payload.hasOwnProperty('ivrLOB'),'Bad value for ivrLOB');
done();
});
});
});
});
function createServer(opts) {
//Note: this is a good pattern, definitely
var handleXml = require(path.resolve('lib', 'handleXml'));
var server = http.createServer(function(req, res) {
handleXml(req, res, function(err) {
res.statusCode = err ? (err.status || 500) : 200;
res.end(err ? err.message : JSON.stringify(req.body));
});
});
server.listen(5999); //TODO: which port should this be listening on? a unused port, surely
return server;
}
That's the standard way of testing a the http endpoints in a node application. But you are not going to want to have a createServer() function in each test. You will have a common function that creates a server that you can use through out your application, including to start the production server.
You right in noticing the having the server listen to a port doesn't actually do anything for you.
For this reason, it's common to have what I call an application factory that starts everything about a server, but does not listen to a port. That way I can access the server from a test or a script. The production app gets booted from a minimal index file:
var createServer = require('./AppFactory');
var server = createServer();
server.listen(5999);

How to make ajax get/post request in express server?

Below is my express server. I am trying to make a get request in ajax, but it turned out failed even though I required jquery at the beginning. It said $ is not defined Other than using jquery ajax, what else can I use to make an API call form RESTful API url?
var express = require('express');
var requestHandler = require('./requestHandler');
var app = express();
var path = require('path');
app.use(express.static(path.join(__dirname, '../client')));
app.get('/homepage', requestHandler.getData);
var port = process.env.PORT || 3000;
app.listen(port);
console.log("Server running at: http://localhost:" + port);
// request handler file:
var express = require('express');
var url = "http://jsonplaceholder.typicode.com/";
module.exports.getData = function (req, res){
$.ajax({
method: 'GET',
url: url+'posts',
success: function(data) {
console.log(data);
res.send(data);
}
});
}
module.exports.getComments = function(userId){
$.ajax({
method: 'GET',
url: url+'/comments',
success: function(data) {
console.log(data);
}
});
}
HTTP GET Request in Node.js Express
var http = require('http');
var options = {
host: 'www.google.com',
path: '/index.html'
};
var req = http.get(options, function(res) {
console.log('STATUS: ' + res.statusCode);
console.log('HEADERS: ' + JSON.stringify(res.headers));
// Buffer the body entirely for processing as a whole.
var bodyChunks = [];
res.on('data', function(chunk) {
// You can process streamed parts here...
bodyChunks.push(chunk);
}).on('end', function() {
var body = Buffer.concat(bodyChunks);
console.log('BODY: ' + body);
// ...and/or process the entire body here.
})
});
req.on('error', function(e) {
console.log('ERROR: ' + e.message);
});
You need to understand things like:
expressjs is serverside code so it can't use jquery ajax like that.
jQuery.ajax() can only be used at view when you load your page in the browser.
You need to use some view engines like jade to create templates and use routers to push the view in the browser. When you have your view in the browser then you can make a reference to the script file which can contain your ajax code to let you have posts and comments.
More information.
Try something like this:
function() {
// Simple POST request example (passing data) :
$http.post("/createProject/"+ id +"", {
projectTitle: pTitle,
userID : id
}).
success(function(data, status, headers, config) {
// this callback will be called asynchronously
// when the response is available
$scope.getProjects();
console.log("project created");
console.log("this is the response data " + data);
}).
error(function(data, status, headers, config) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
};
Also please note. you will call this from an external JavaScript file. One the express server you will only have "routes" and from external javascript files you can perform HTTP calls on those routes.
Update
#Someone, the express framework is very popular to setup a web server in Node. You can use different render engines to render the view and pass information to the user. This is a very simple example from the Express website listening to two urls (/posts and /comments).
var express = require('express');
var app = express();
app.get('/posts', function (req, res) {
res.send('Render posts!');
});
app.get('/comments', function (req, res) {
res.send('Render comments');
});
var server = app.listen(3000, function () {
var host = server.address().address;
var port = server.address().port;
console.log('Example app listening at http://%s:%s', host, port);
});

nodejs https callback not updating global variable [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 9 years ago.
I'm setting up a quick proxy server in nodejs to proxy a API request for an Angular application. The proxy endpoint is a service I do not control and does not support CORS or JSONP. For testing, I setup a dummy http server in the code example below, but in reality this is a remote domain.
I'm pretty sure my problem is due to asynchronous processing of nodejs, but I don't know how to solve this. My generic makeRequest() function seems to work ok, it gets the expected response back from the remote server. I can see the resultData string in the on('data') and on('end') event handlers with success. However, I don't know how to get the response back to the browser inside restify's req.json() method.
Help!
var restify = require('restify');
var querystring = require('querystring');
var https = require('https');
var http = require('http');
var port = '8080';
var server = restify.createServer({
name : "ProxyService"
});
var responseData = '';
// Generic request function
function makeRequest(host, endpoint, method, data, headers) {
var dataString = JSON.stringify(data);
var options = {
host: host,
path: endpoint,
method: method,
headers: headers
};
var req = https.request(options, function proxyrespond(res) {
res.on('data', function(data) {
console.log("DATA----", data);
responseData += data;
});
res.on('end', function() {
//probably need to do something here
});
});
req.end();
req.on('error', function(e) {
console.error(e);
});
console.log("OPTIONS: ", options);
console.log("DATA: ", responseData);
req.write(dataString);
req.end();
};
server.get('/getlist', function respond(req, res, next){
var headers = {'Connection': 'close',
'Content-Type': 'application/json' };
var host = 'localhost:9000';
var endpoint = '/getlist';
var auth = {auth-id: '12345', auth-token: '6789'}
var data = req.data || '';
// add authentication parms to the endpoint
endpoint += '?' + querystring.stringify(auth);
// if the request has headers, add them to the object
for (var key in res.headers) {
headers[key] = rest.headers[key];
};
makeRequest(host, endpoint, 'GET', data, headers);
res.headers = {Connection: 'close'};
res.json( responseData );
return next();
});
http.createServer(function (req, res) {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.write('request successfully proxied!' + '\n' + JSON.stringify(req.headers, true, 2));
res.end();
}).listen(9000);
server.listen(port, function(){
console.log('%s listening at %s ', server.name , server.url);
});
Return via a callback function:
// Generic request function
function makeRequest(host, endpoint, method, data, headers, callback) {
.........
var req = https.request(options, function proxyrespond(res) {
// DO NOT declare responseData as global variable
var responseData = '';
res.on('data', function(data) {
responseData = responseData + data;
});
res.on('end', function() {
// RETURN VIA CALLBACK
callback(responseData)
});
});
.........
};
server.get('/getlist', function respond(req, res, next){
.........
makeRequest(host, endpoint, 'GET', data, headers, function (responseData) {
res.headers = {Connection: 'close'};
res.json( responseData );
return next();
});
});

Categories