NodeJS... Saving JSON to a Variable - javascript

I'm a bit of a newbie to NodeJS, but I've looked around all over and can't seem to find a solution to my problem below. I'm sure it's something simple, but thanks in advance for all help you can give me!
I'm trying to make a simple JSON scraper via NodeJS. All I need is for JSON to be stored to a variable. The problem is, I'm using Require, and their example just logs it to console. I've tried adding a variable after it's logging to the console, but I'm just getting undefined. Here's my code below, it's pretty simplistic so far :)
// var jsonVariable; Doesn't work, shown as a test
function getJSON(url){
var request = require("request")
request({
url: url,
json: true
}, function (error, response, body) {
if (!error && response.statusCode === 200) {
console.log(body) // Print the json response
//return body; This doesn't work, nor does making a global variable called json and assigning it here. Any ideas?
//jsonVariable = body; // This also doesn't work, returning undefined even after I've called the function with valid JSON
}
})
}
Once again, thanks so much for any help you can give me :)

The problem is that the request method is asynchronous, but you're trying to synchronously return a result. You'll need to either make a synchronous request (which doesn't appear to be possible with the request package you're using), or else pass a callback function to be called when the request responds successfully. e.g.:
var request = require("request")
function getJSON(url, callback) {
request({
url: url,
json: true
}, function (error, response, body) {
if (!error && response.statusCode === 200) {
callback(body);
}
});
}
getJSON('http://example.com/foo.json', function (body) {
console.log('we have the body!', body);
});

If you use 'return body' where does it return to? That function is being called as a parameter to the request() function. You also cannot define a variable in your anonymous function because you will not have access to it outside of that scope.
What you need to do is define a variable outside of function getJSON() and then save body to that.
e.g.,
var result;
function getJSON(url){
var request = require("request")
request({
url: url,
json: true
}, function (error, response, body) {
if (!error && response.statusCode === 200) {
result = body;
}
});
}

Related

node.js - making result available globally (Request module)

I'm trying to process the returned JSON result from the request
so I need to expand its scope outside this request call.
To do that I declared data variable with an empty string and assign the result to this data but it doesn't print the result.
How can I accomplish this?
module.exports = function(callback) {
var request = require("request")
var url = "http://sheetsu.com/apis/94dc0db4"
var data = "";
request({
url: url,
json: true
}, function (error, response, body) {
if (!error && response.statusCode === 200) {
callback(body)
data = body;
}
})
console.log(data);
}
This is classic async confusion : your console.log call will happen before the http request callback.
Your script is executed in this order:
request() is executed
console.log(data)
request() callback function, where you asign data a value
If you want to print data, you must do it inside the request callback function. The async module, is very useful when performing async tasks, specially if you need to perform tasks in a specific order and use the data from this requests.

JS Function executing too fast

I'm doing a JSON call like this:
var desc = getItemDescriptions(xxx);
function getItemDescriptions(xxx) {
var url = "xxx;
var info = {};
request({
url: url,
json: true
}, function (error, response, body) {
if (!error && response.statusCode === 200) {
info ["..."] = body.result[xxx].yyy;
info ["..."] = body.result[xxx].yyy;
info ["..."] = body.result[xxx].yyy;
info ["..."] = body.result[xxx].yyy;
info ["..."] = body.result[xxx].yyy;
}
})
return info;
}
My Problem is, the JSON request need some time to get response back... and my function doesn't wait for this response. The Function returns the empty array without waiting.
How can i wait for response and then return the filled array?
thx
Its not like executing fast, it is the way javascript runs statement after statement. To get the data you need to do that in success callback function, the data would be available only when the server response comes back as its asynchronous call by the time response comes your javascript executes next statements.
Juhana already linked to you the best place to get a good solution. How to return the response from an async call
A quick and dirty hack would be (if request is a jQuery-like Ajax-function) to make the request synchronus.
This might be done by adding async: false to the first parameter passed to request:
request({ url: url,json: true, async: false}, function ....
That way return info will be executed AFTER your request has finished.
HTH
Georg

REST call always return undefined (Node.JS) [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 7 years ago.
I'm still new to Node.JS and I'm trying to call a REST API using GET method.
I use 'request' package from this link. The call actually works but when I try to return the response body from other .JS file, I get 'undefined'.
Here is my 'first.js'
var request = require('request');
var first = function (){
};
first.prototype.getValue = function (value){
var thpath = somePath + value;
var postheaders = {
'Content-Type': 'x-www-form-urlencoded'
};
var options = {
url : 'https://' + thpath,
method : 'GET',
headers : postheaders,
};
var data_rec = "";
request(options, function (error, response, body) {
if (!error && response.statusCode == 200) {
data_rec = JSON.parse(body);
console.info(data_rec);
return data_rec;
} else return "failed to get";
});
};
module.exports = first;
Here is my 'second.js'
var first = require('./first');
var instance = new first();
var val1 = instance.getValue(someValue);
console.info(val1);
The 'console.info(data_rec)' from 'first.js' returns a JSON (which means that the call is working). However, 'console.info(val1)' from 'second.js' returns 'undefined'. Can anybody find the solution?
Update:
I am able to get the solution by using sync-request package.
var val1 = instance.getValue(someValue);
console.info(val1);
instance.getValue is an asynchronous method. Meaning javascript vm wont wait for response, it just goes on with next line ie console.info(val1); Ajax request takes time and response comes in only after some time, and triggers the success function.Till then val1 is undefined
request(options, function (error, response, body) {
if (!error && response.statusCode == 200) {
data_rec = JSON.parse(body);
console.info(data_rec);
return data_rec;
} else return "failed to get";
});
See that console.info(data_rec); is given inside the success function, success function is something that get called after response is successfully retrieved
You're trying to return asynchronous response in a synchronous manner which is not possible.
When you make the call, first() is executed and returned with no value and then async call completes. So console.log prints correctly, but you won't receive the value.
Modify this part of code
request(options, function (error, response, body) {
if (!error && response.statusCode == 200) {
data_rec = JSON.parse(body);
console.info(data_rec);
return data_rec;
} else return "failed to get";
});
to this
var request = request(options, function (error, response, body) {
if (!error && response.statusCode == 200) {
data_rec = JSON.parse(body);
console.info(data_rec);
}
});
return request.then(function (res) {
if (res.statusCode >= 300) {
return "failed to get";
} else {
return res.body.toString()
}
})

JSON object but can't parse

I need to do a lookup onto an itunes url which throws the json, in my nodejs based backend, i am using requests module of nodejs to get the json, and it indeed returns me the json as well, but the moment i try parsing it doesn't return me internal objects, however calls like stringify or JSON.parse just work without any exception.
sample url https://itunes.apple.com/lookup?id=477091027
//sample url https://itunes.apple.com/lookup?id=477091027
request(itunesUrl, function (error, response, body) {
if (!error && response.statusCode == 200) {
var jsonbody = JSON.stringify(body.trim());
var obj = JSON.parse(jsonbody);
console.log(obj);
/*for(var myKey in obj)
{
console.log("key:"+myKey+", value:"+obj[myKey]);
}*/
//none of these show value in them
appinfo.appname = obj.results[0].trackName;
appinfo.appImage = obj.results[0].artworkUrl60;
appinfo.appCategory = obj.results[0].genres[0];
}
});
I am at my wits end now
Actually, you are stringifying the json before parse-ing it again :
var jsonbody = JSON.stringify(body.trim());
var obj = JSON.parse(jsonbody);
If body is supposed to contain json, then you directly should do
var obj = JSON.parse(body);
you just need to add the parameter json:true
request({url:itunesUrl, json:true}, function (error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body.results[0].trackName)
}
});
Even though Ninetainedo's answer looks correct, the docs suggest that you can use json: true as a parameter in the request options. This will automatically parse the json into a object, removing the need for the JSON.parse() line.
See https://github.com/request/request#requestoptions-callback

how return data since a GET request with node.js

I have a little trouble with an Node application, the problem is: I have an Script in a web site "x" and this script calls a function that is on another server (like analytics), I'm calling the function with ajax and when the function returns the data, happen some curious, when I check the network with Developer Tools in Chrome, the callback shows the response like I wanted in JSON format, but not show me data. My code:
var xml2js = require('xml2js'),
http = require('http'),
request = require('request');
var parserController = function (aw){
console.log('Parse Controller load');
aw.get('/ads/:keyword/:sid/:pid/:count', function (req,res){
res.setHeader('Content-Type', 'application/json');
request('http://'+req.params.sid+'.'+req.params.pid+'.autoweb-xml.com/feed?&sid='+req.params.sid+'&auth=2Al5&subid=&q='+req.params.keyword+'&ip=127.0.0.1&ua=Mozilla/5.0%20(Windows%20NT%206.1;%20WOW64;%20rv:26.0)%20Gecko/20100101%20Firefox/26.0&ref=awebads.lan&count='+req.params.count+'&state=&city=', function (error, response, body) {
if (!error && response.statusCode == 200) {
var parser = xml2js.parseString;
var data = '';
parser(body,{explicitRoot : false}, function (err, result){
if(!err){
data = result;
dataP=data.results[0];
dataS=dataP.sponsored[0];
console.log(dataS.listing);
return res.send(dataS.listing);
}
else
{
console.log(err);
}
})
}
})//en del request
});
};
and my call function is:
var xhr = $.ajax({
type:'GET',
url:'http://HOST/ads/'+configParams.keyword+'/'+configParams.envSource+'/'+configParams.envPublisher+'/'+configParams.envCount,
dataType : 'jsonp',
async: false,
crossDomain : true
})
xhr.done(function (data){
console.log(data);
data.forEach(function(item){
window.collections.ads.add(item);
});
}).fail(function (err) {
//console.log('failed');
//console.log(err)
});
when I display the data in the console, this part show me the XMLHTTPRequest, thanks in advance for your help
You are sending JSON:
the callback shows the response like I wanted in JSON format
… but the client is expecting JSON-P
dataType : 'jsonp',
Either:
Tell the client to expect JSON (or just remove the dataType line and let it use the Content-Type header) and set Access-Control-Origin on the response headers to give the site permission to access it cross-domain or
Send JSON-P back instead (look at callback in the query string, send Content-Type: application/javascript (not JSON!), and return callback_value(your_json); as the response body.
In case of jsonp you need a callback function and then return your response in that callback.

Categories

Resources