JavaScript return not working as expected - javascript

This is a total newbie questions, and I'm trying to learn JavaScript and node.js. I'm attempting to use request to grab information from an api, and then store the information in an array that I can then manipulate.
Here is my code so far:
const request = require('request');
var url = "https://www.predictit.org/api/marketdata/ticker/CHINA.INAUGURAL.2017";
var info = request(url, function(err, res, body){
var json = JSON.parse(body);
return json;
})
However, the info variable seems to only store something that I think is related to the request call, but I'm not sure. If I replace return json with console.log(json) then it prints the array immediately, though I can't get it to store it.
I would like to tell node info['ID'] and have it return 2835

Node does not work like this. Node is asynchronous.
You can try this,
var info;
request(url, function(err, res, body){
info = JSON.parse(body);
});

Looks like you' re requesting xml file from that url. You can install xml2js library for nodejs by typing npm install xml2js and let it parse the xml for you. After that
var parseString = require('xml2js').parseString;
var url = "https://www.predictit.org/api/marketdata/tick /CHINA.INAUGURAL.2017";
var info = request(url, function(err, res, body){
parseString(body, function (err, result) {
info = JSON.parse(JSON.stringify(result));
});
return info;
})

I hope this one should work,
request('https://www.predictit.org/api/marketdata/ticker/CHINA.INAUGURAL.2017',
function (err, res) {
if (err) {
console.log('ERROR: Something went wrong');
}
else {
parseString(responce.body, function (err, result) {
res.json(result);
});
}
});

I think that data is stored into 'info' variable but you're using it before data is stored.
Here it takes some time for API call to process and get data. Then it will be stored into 'info' variable. Have a timeout of 5s and then try console.log(info[1]) and would return expected value.
This is due to asynchronous nature of nodejs. Here your code might be executing info[1] before it is set by API call.

Related

Using base64 function results in InvalidCharacterError

What I want to do is using base-64 module method, in my node.js + express project.
The code is like this.
router.get('/list', function(req, res, next) {
client.query('SELECT * FROM Document',function(err, row){
if(err) throw err;
var base64 = require('base-64');
row.forEach(e => {
e.text = base64.decode(e.text);
});
res.render('main/list',{title:"###", row:row});
})
});
In this function, there are MySQL query in the callback.
The text is the base-64 encoded value of the Database.
But, the base64.encode() doesn't work in this code, but results in InvalidCharacterError
how should I use correctly?
You can use nodejs built-in functions
let original = 'abcdefrgsdfdsf123123123123';
let testCode64 = Buffer.from(original).toString('base64')
let testDecode64 = Buffer.from(testCode64, 'base64').toString('utf-8');

nodejs sends empty response before data retrieved from mongodb

When I use jQuery ajax to retrieve data from nodejs (with express4), nodejs sends empty response back before data loaded from mongodb.
This is the message from nodejs console:
GET /query?uid=1 - - ms - -
And this is the error message from Chrome console:
GET http://192.168.1.105:3000/query?uid=1 net::ERR_EMPTY_RESPONSE
I can confirm that data are correctly loaded from mongodb because data can be printed on nodejs console after nodejs sent the empty response. And this is exactly the problem. Why nodejs sends reponse to client before data have been prepared?
I know nodejs is asynchronous and I pay much attention to this great feature, but I still have this problem.
This is my client code:
$.getJSON('/query', {uid:1}, function(response) { console.log('finished!'); });
And this is my server code:
var express = require('express');
var mongodb = require('mongodb');
var GeoJSON = require('geojson');
var strftime = require('strftime');
var router = express.Router();
var MongoClient = mongodb.MongoClient;
router.get('/query', function(req, res, next) {
var url = "mongodb://localhost/example_db";
var collection_name = "example_collection";
var poi = req.query.poi ? req.query.poi.split("||") : null;
var time = req.query.time;
var uid = req.query.uid;
var condition = {};
if (poi) condition.poiname = {$in: poi};
if (time) condition.checkin_time = {$gte:new Date(time.start_time), $lte:new Date(time.end_time)};
if (uid) condition.uid = parseInt(uid);
MongoClient.connect(url, function(err, db) {
if (err) console.log('connection error');
var collection = db.collection(collection_name);
collection.find(condition).sort({checkin_time:1}).toArray(function(err, result) {
if (err) {
console.log(err);
return res.send('error!');
}
if (!result) return res.send('no data');
//This line prints the result after empty response has been sent.
console.log(result);
var data = {};
data['geojson'] = GeoJSON.parse(result, {Point:'loc', include:['poiname', 'uid', 'checkin_time']});
res.json(data);
db.close();
});
});
My data are a little bit large, 12G stored in mongodb. So it usually takes about 3 minutes or more to complete the query. When I use findOne to retrieve only a single document, this is no problem.
Does the data size cause the problem?
Try GeoJSON.parse with callback
var data = {};
GeoJSON.parse(result, {Point:'loc', include:['poiname', 'uid', 'checkin_time']}, function (geojson) {
data['geojson'] = geojson;
res.json(data);
db.close();
});

Node.js - Asynchronous JSON Query

I apologize if this is a stupid question, but I am new to Javascript and Node.js really hurts my head because it is asynchronous.
My goal is to query for a JSON object from an API and be able to work with it. I have tried to look for questions and answers on what I should be doing but none of it really makes sense to me, so I am hoping to learn by just seeing proper code.
var request = require('request');
var url = 'url here';
var temp;
var done = false;
request(url, function (error, response, body) {
if (!error) {
temp = body;
done = true;
console.log(temp);
} else {
console.log(error);
}
});
if (done){
console.log(temp);
}
Can someone please walk me through the proper way to restructure my code?
The function you are creating with the line
request(url, function (error, response, body) {
is not executed until the response is received. The rest of your code continues to run. Think of the flow something like this:
var request = require('request');
var url = 'url here';
var temp;
var done = false;
request(url, XXX);
if (done){
console.log(temp);
then when the response is received (perhaps much later on) the function XXX is executed.
As you can see, done will always be false when the line
if (done){
is executed.

Node.JS where to put the response.end()

I'm developing a simple NODE.JS application. First I create an httpServer using http module. Then I route the request to the requestsHandlers.js page. 'Response' parameter cames from the creation of the httpServer. Process1, process2 and process3 should write an answer to the page. This is the objective of this app, that process1, process2 and process3 write its respective text.
requestHandlers.js
var process1 = require("./process1");
var process2 = require("./process2");
var process3 = require("./process3");
function iniciar(response) {
console.log("Manipulador de peticiĆ³n 'iniciar' fue llamado.");
response.writeHead(200, {"Content-Type": "text/html"});
process1.fc1(response);
process2.fc2(response);
process3.fc3(response);
//response.end() //WHERE DO I PLACE IT?
}
As you can see, the response parameter is passed to process1.js, which after parsing some data shoud echo some information.
process1.js
var request = require('request')
function fc1 (response){
var url = 'http://webpagethatreturnsJSONfile.com/'
//Download webpage data and parses it
request(url, function(err, resp, body) {
if (err)
throw err;
var jsonResult = JSON.parse(body);
response.write("Number:" + jsonResult.number + '');
//response.end() //WHERE DO I PLACE IT?
});
}
exports.fc1 = fc1;
The point is that I don't know where to put 'response.end()'. Each process takes some time and I want to 'end' when all processes have echo their text.
How could I do it?
I don't know if the code I've attached is enough for helping me.

AJAX call with Express

I am trying to append HTML dynamically with Express framework in a static HTML file that my server serves. I've found about the cheerio module that does exactly what I want, but I was wondering if there is a much cheaper way for the system instead of loading the whole HTML and appending a string.
I searched about AJAX and how to communicate with the client but I didn't manage to make it work. The code I am using with cheerio is:
exports.modify = function(req, res){
var html = fs.readFileSync(__dirname + '/../public/index.html', 'utf8');
var $ = cheerio.load(html);
var scriptNode = '<p>Source code modified</p>';
$('body').append(scriptNode);
fs.writeFile(__dirname + '/../public/index.html', $.html(), function (err) {
if (err) throw err;
console.log('It\'s modified!');
});
res.send($.html());
};
How can I do it in more 'proper' way (maybe with AJAX call)? Any suggestions would be more than welcome.
Assuming you want to handle JSON as a data type then you can setup another specific route or you can filter the request type within the current route handler :
exports.index = function(req, res) {
var data = someData.fetch();
switch(req.format) {
case 'json':
res.json(data);
break;
default:
res.render('template', {
data:data
});
}
};

Categories

Resources