Im a node JS beginner and i need help with exporting the console log data into HTML page.
I found this great example at the GitHub: https://github.com/benbuckman/nodejs-ebay-api
my problem is this: I managed to implement it with my needs - but I don't manage to extract the data out of the console log ! I simply want to display it in the browser and not in the console log.
Any suggestions ?
Currently im working on the "single" example - here's my code so far, which has many errors:
// example simple request to FindingService:findItemsByKeywords
var ebay = require('../index.js');
var http = require('http');
var express = require('express');
var app = express();
var io = require('socket.io');
app.set('port', process.env.PORT || 5000);
app.get('/get', function(req, res) {
console.log('inside get');
// for avoiding crossbrowser-error
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
res.header('Content-Type','application/json');
var params = {};
params.keywords = [ "cat"];
params['paginationInput.entriesPerPage'] = 10;
ebay.ebayApiGetRequest({
serviceName: 'FindingService',
opType: 'findItemsByKeywords',
appId: 'MYAPPID', // FILL IN YOUR OWN APP KEY, GET ONE HERE: https://publisher.ebaypartnernetwork.com/PublisherToolsAPI
params: params,
// filters: filters,
parser: ebay.parseItemsFromResponse // (default)
},
// gets all the items together in a merged array
function itemsCallback(error, items) {
if (error) throw error;
console.log('Found', items.length, 'items');
for (var i = 0; i < items.length; i++) {
console.log('- ' + items[i].title);
}
}
);
});
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
console.log('Listening on port 5000...');
It looks like you're using Express, and specify a single GET API endpoint on the URL /get. From what I understand, you want to see the output from the browser and not just the console (the console you're able to see with the console.log messages). Express will return to the user who makes the HTTP request what you put in res.send(). So for example, if you were to add:
res.send("hello");
to the end of the `app.get' function, you would see "hello" in the browser. Note that you can only do that once, so you'll need to bundle all the information you want to send to the browser in an object, and then send that.
It looks like what you want to see is the data collected from within the itemsCallback function. So to make things simple, you could just send the items back. For instance:
function itemsCallback(error, items) {
if (error) throw error;
console.log('Found', items.length, 'items');
for (var i = 0; i < items.length; i++) {
console.log('- ' + items[i].title);
}
res.send(items); // sends the items in the HTTP response
}
As a side note, you don't need to include the http module, and instead can start the server like this:
app.listen(app.get('port'), function() {
console.log('Express server listening on port ' + app.get('port'));
});
Related
Here is the guide I'm basing my code off of: https://github.com/elad/node-cluster-socket.io
Although 9 threads are started, only one is in use at a time, and it's always the same thread that gets used. Their code works fine, but I've modified it to work with my program, and that's where I'm having issues.
manager.js:
var express = require('express'),
cluster = require('cluster'),
net = require('net'),
sio = require('socket.io'),
sio_redis = require('socket.io-redis');
var port = 3000,
num_processes = require('os').cpus().length;
if (cluster.isMaster) {
// This stores our workers. We need to keep them to be able to reference
// them based on source IP address. It's also useful for auto-restart,
// for example.
var workers = [];
// Helper function for spawning worker at index 'i'.
var spawn = function(i) {
workers[i] = cluster.fork();
// Optional: Restart worker on exit
workers[i].on('exit', function(code, signal) {
console.log('respawning worker', i);
spawn(i);
});
};
// Spawn workers.
for (var i = 0; i < num_processes; i++) {
spawn(i);
}
// Helper function for getting a worker index based on IP address.
// This is a hot path so it should be really fast. The way it works
// is by converting the IP address to a number by removing non numeric
// characters, then compressing it to the number of slots we have.
//
// Compared against "real" hashing (from the sticky-session code) and
// "real" IP number conversion, this function is on par in terms of
// worker index distribution only much faster.
var worker_index = function(ip, len) {
var s = '';
for (var i = 0, _len = ip.length; i < _len; i++) {
if (!isNaN(ip[i])) {
s += ip[i];
}
}
return Number(s) % len;
};
// Create the outside facing server listening on our port.
var server = net.createServer({ pauseOnConnect: true }, function(connection) {
// We received a connection and need to pass it to the appropriate
// worker. Get the worker for this connection's source IP and pass
// it the connection.
var worker = workers[worker_index(connection.remoteAddress, num_processes)];
worker.send('sticky-session:connection', connection);
}).listen(port);
} else {
// Note we don't use a port here because the master listens on it for us.
var server_local = require('./server.js');
server_local.startServer(0, function(server, io) {
// Here you might use middleware, attach routes, etc.
// Don't expose our internal server to the outside.
// Tell Socket.IO to use the redis adapter. By default, the redis
// server is assumed to be on localhost:6379. You don't have to
// specify them explicitly unless you want to change them.
io.adapter(sio_redis({ host: 'localhost', port: 6379 }));
// Here you might use Socket.IO middleware for authorization etc.
// Listen to messages sent from the master. Ignore everything else.
process.on('message', function(message, connection) {
if (message !== 'sticky-session:connection') {
return;
}
// Emulate a connection event on the server by emitting the
// event with the connection the master sent us.
server.emit('connection', connection);
connection.resume();
});
});
}
server.js:
var fs = require('fs');
var satJS = require('satellite.js');
var express = require('express');
var app = new express();
var serv = require('http').Server(app);
var sio = require('socket.io');
...
exports.startServer = function(port, callback) {
updateSatelliteData(function() {
server = app.listen(port);
io = sio(server);
initalize(io);
callback(server, io);
console.log("Server started");
});
}
function initalize(io) {
//Web stuff
app.get('/', function(req, res) {
res.sendFile(__dirname + '/client/index.html');
});
app.use('/client', express.static(__dirname + '/client'));
io.sockets.on('connection', function(socket) {
...
}
etc.
}
I am trying to implement a node http proxy for the first time with my simple twitter tweeter. I have never used this before and tried following the docs (https://github.com/nodejitsu/node-http-proxy) with no luck. Can anyone point me in the right direction? Also, is it okay to run this locally on a mac? Thanks
var express = require('express');
var app = express();
var port = 8300;
var twitter = require('twitter');
var twit = new twitter({ keys and stuff })
var http = require('http'),
httpProxy = require('http-proxy');
twit.post('statuses/update', {status: "Hello world!"}
//this works
httpProxy.createProxyServer({target:'http://localhost:3000'}).listen(3000);
// Create your target server--- WHat exactly does this mean??
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(3000);
You should not use this lib for proxing you request. This lib is for make your own proxy server. Look at example how to use proxy with twitter lib
When I type somedomain.com/some_api_url?_var1=1 into a browser, the response is {"1":"descriptive string"}, where 1 is a numerical index variable whose value could range from 1 to n. And where "descriptive string" is some text that summarizes what the index represents.
How can I integrate the JSON response from the somedomain.com/some_api_url?_var1=1 api url into the very simple Node.js and Express.js example below?
For testing purposes, the very simple app.js shown below returns "Hello World" when the user requests http : // localhost : 3000 from their web browser. What specific changes need to be made to the code below so that the web browser responds to the request with:
Index is: 1
Description is: descriptive string
instead of responding with "Hello World"?
Here is the current code for app.js:
var express = require('express');
var http = require('http');
var app = express();
app.get('/', function (req, res) {
res.send('Hello World!');
});
app.listen(3000, function () {
console.log('Example app listening on port 3000!');
});
Here is my current attempt, which results in the console printing Got a response: undefined, and with the browser remaining hung up because nothing is returned to the browser as a response:
var express = require('express');
var http = require('http');
var app = express();
app.get('/', function (req, res) {
var url = 'somedomain.com/some_api_url?_var1=1';
http.get(url, function(res){
var body = '';
res.on('data', function(chunk){
body += chunk;
});
res.on('end', function(){
var fbResponse = JSON.parse(body);
console.log("Got a response: ", fbResponse.picture);
});
}).on('error', function(e){
console.log("Got an error: ", e);
});
});
app.listen(3000, function () {
console.log('Example app listening on port 3000!');
});
The get example code was adapted from the example at this link.
You actually forgot to return response res.send(data). Change you endpoint code like this. Also use different variable name for internal response object. I am using response here.
app.get('/', function (req, res) {
var url = 'somedomain.com/some_api_url?_var1=1';
http.get(url, function(resonse){
var body = '';
resonse.on('data', function(chunk){
body += chunk;
});
resonse.on('end', function(){
var body = JSON.parse(body);
var text = '';
for (var key in body){
text += 'Index is: ' + key +
'\nDescription is: ' + body[key]
}
// The Description is: "descriptive string"
console.log("Got a response: ", fbResponse);
res.send(text);
});
}).on('error', function(e){
console.log("Got an error: ", e);
});
});
Try this code with express 4.14.0
As #Zohaib-Ijaz pointed out, res is redefined and won't work for the res.send without a rename. This code also calls itself for demo purposes (so you can ignore app.get('/some_api_url', for the moment.
Then once the http.get is done, work with the object and print as you like. Keep in mind this code is not defensive against errors in the JSON.
var express = require('express');
var http = require('http');
var app = express();
const PORT = 3000;
app.get('/', function (req, res) {
var url = `http://localhost:${PORT}/some_api_url?_var1=1`;
http.get(url, function (resInner) {
var body = '';
resInner.on('data', function (chunk) {
body += chunk;
});
resInner.on('end', function () {
var fullResponse = JSON.parse(body); // {"343",:"I've heard 344 is more"}
// code to pair the keys with their data in plain js
var indexKeys = Object.keys(fullResponse);
var replies = indexKeys.map((key) => {
return `Index is ${key}\nDescription is ${fullResponse[key]}`;
});
//note this injection of a <pre> tag is just so modern browsers
// will respect the newlines. it is not an HTML document or JSON
res.send(
`<pre>${replies.join("\n")}</pre>`
);
});
}).on('error', function (e) {
console.log("Got an error: ", e);
});
});
app.get('/some_api_url', (req, res) => {
var var1 = req.query.var1 || "343";
var value = `I've heard ${parseInt(var1) + 1} is more`;
var reply = {};
reply[var1] = value;
res.send(JSON.stringify(reply));
});
app.listen(PORT, function () {
console.log(`Example app listening on port ${PORT}!`);
});
You seem to be mixing up Express, native HTTP module, and HTTP client.
Here is the serverside code for sending the response you are looking for.
var express = require('express');
var http = require('http');
var app = express();
// our "database"
var database = ['APPLE', 'BOOK', 'CAT', 'DOG', 'ELEPHANT'];
app.get('/', function (req, res) {
// apply query parsing only of the query parameter is specified
if ('itemId' in req.query) {
var itemId = req.query.itemId;
// index less than 0 will not yield anything from our "database"
if (itemId < 0) {
res.status(400).send('Invalid item id');
// the item index corresponds to one of the items in the "database"
} else if (itemId < database.length) {
var result = 'Index: ' + itemId + '<br>Description: ' + database[itemId];
res.send(result);
// index exceeds the size of the array, so nothing will be found
} else {
res.status(404).send('Item not found');
}
// render the default homepage
} else {
res.send('Request format: http://localhost:3000/?itemId=n');
}
});
app.listen(3000, function () {
console.log('Example app listening on port 3000!');
});
To see it in action, load http://localhost:3000/?itemId=0 in the browser. Valid itemId values are 0 to 4.
I have two node servers and I need to combine them so one server has the functionality of both. They were set up a little differently and I'm not sure how to resolve it.
The first server has the require statements at the top, routes in the middle and creates the server at the bottom like this:
var express = require('express');
var routes = require('./routes');
etc..
// middleware
// routes
http.createServer(app, function(req, res){
// get files
// check for errors
}).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
The second one looks like this:
var express = require('express')
, app = express()
, server = app.listen(80)
, io = require('socket.io').listen(server)
, fs = require('fs')
var arr= [];
app.get('/aRoute', function(req, res) {
res.writeHead(200);
var data = {
// parse query string
};
arr.push(data);
io.sockets.emit('update', data);
res.end("OK");
});
app.get('/someOutput', function(req, res) {
res.writeHead(200);
res.end(JSON.stringify(footData));
});
io.sockets.on('connection', function (socket) {
});
I cut pasted part of it so now the first server script looks (roughly) like this.
// All imports
var express = require('express');
var routes = require('./routes');
var mongoose = require('mongoose');
var user = require('./routes/user');
var http = require('http');
var path = require('path');
var fs = require('fs');
var multer = require('multer');
var connect = require('connect');
var methodOverride = require('method-override');
var io = require('socket.io');
// middleware
// routes
// trying to make this a route
var arr= [];
app.get('/aRoute', function(req, res) {
res.writeHead(200);
var data = {
// parse query string
};
arr.push(data);
io.sockets.emit('update', data);
res.end("OK");
});
app.get('/someOutput', function(req, res) {
res.writeHead(200);
res.end(JSON.stringify(footData));
});
// THIS GIVES ME ERRORS RIGHT HERE
io.sockets.on('connection', function (socket) {
});
http.createServer(app, function(req, res){
// get files
// check for errors
}).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
Combining the two scripts has resulted in an error listed below at the line listed below.
io.sockets.on('connection', function (socket) {
^
TypeError: Cannot call method 'on' of undefined:
// THIS GIVES ME ERRORS RIGHT HERE
io.sockets.on('connection', function (socket) {
});
I don't understand why I'm getting this error after changing the two require statements and moving the server creation and listening to the bottom of the server. Does anyone know how I can fix this?
You're requiring socket.io, which has a .listen method, not an .on method. Once you call .listen, you'll get back an object that has the .on method you're trying to use.
io = require('socket.io').listen(server);
(You're also missing server, which is created in the second script by calling express().listen(somePortNumberLike80)
You can't just copy and paste code and expect it to work, really.
I'm going through a Node, Express, & Socket.io chat tutorial. I decided to use Redis to store the chat history and have successfully set it up so that my information is correctly posting to the database. I am now trying to access that information to use on the client-side (in this case I'm trying to access the list of users currently in the chat so I can show them to the side of the chat). I am using $.getJSON to make a GET request. Right now I have it setup so that the file it tries to access only has this JSON object : {"dog" : "2","cat":"3"} just to test it, and that is working, but I'm not sure where to go from there because anytime I try adding a function into that file, even if I specify to return a JSON object and call that function, the request stops returning the correct information.
For example I tried :
var data = function(){
return {"dog" : "2","cat":"3"}
}
data();
and that doesn't return anything ( I understand that when I make a GET request the function isn't run, but it doesn't even return that text, and if it doesn't run a function than I'm not sure how I can access redis from this file)
Here's what I'm thinking:
var redis = require('redis')
//figure out how to access the redis client that I have at localhost:6379, something like var db = redis.X
//and then call (for example) db.smembers('onlineUsers') and be returned the object which I can iterate through
Here's my relevant code:
server.js:
var jade = require('jade');
var PORT = 8080;
var redis = require('redis');
var db = redis.createClient();
var pub = redis.createClient();
var sub = redis.createClient();
var http = require('http');
var express = require('express');
var app = express();
var server = http.createServer(app);
var io = require('socket.io').listen(server);
server.listen(PORT, function(){
console.log("Now connected on localhost:" + PORT)
});
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.set("view options", {layout: false});
app.use(express.static(__dirname + '/public'));
app.get('/', function(req, res){
res.render('home');
});
io.sockets.on('connection', function(client){
sub.subscribe("chatting");
sub.on("message", function (channel, message) {
console.log("message received on server from publish");
client.send(message);
});
client.on("sendMessage", function(msg) {
pub.publish("chatting",msg);
});
client.on("setUsername", function(user){
pub.publish("chatting","A new user in connected:" + user);
db.sadd("onlineUsers",user);
}
);
client.on('disconnect', function () {
sub.quit();
pub.publish("chatting","User is disconnected :" + client.id);
});
});
script.js:
$(document).ready( function(){
$client = io.connect();
initialize();
});
var setUsername = function(){
var username = $("#usernameInput").val();
if (username)
{
var user = username;
$client.emit('setUsername', username);
$('#chatControls').show();
$('#usernameInput').hide();
$('#usernameSet').hide();
showCurrentUsers();
}
}
var showCurrentUsers = function(){
$('#list_of_users').empty();
$.getJSON('getusers.js', function(data){
for (var i = 0; i < data.length; i++){
$('list_of_users').append("<li>"+data[i]+"</li>")
}
})
}
var sendMessage = function(){
var msg = $('#messageInput').val();
var username = $("#usernameInput").val();
if (msg)
{
var data = {msg: msg, user: username}
$client.emit('message', data);
addMessage(data);
$('#messageInput').val('');
// populate(username,msg);
}
}
var addMessage = function(data) {
$("#chatEntries").append('<div class="message"><p>' + data.user + ' : ' + data.msg + '</p></div>');
}
// var populate = function(username,msg) {
// var data ;
// }
var initialize = function(){
$("#chatControls").hide();
$("#usernameSet").on('click', setUsername);
$("#submit").on('click',sendMessage);
showCurrentUsers();
}
and right now all that the getusers.js file has in it is:
{"dog" : "2","cat":"3"}
It looks like you're expecting your call to $.getJSON to load and execute the javascript it loads. It doesn't work this way. You need to make a node endpoint (via a route) which renders the JSON. The node endpoint would then do the data manipulation / querying redis:
Node:
In routes.js:
app.get('/chatdata', ChatController.getChatData);
In ChatController.js (manipulate, create the data as you like here)
exports.getChatData = function (req, res) {
var data = function(){
return {"dog" : "2","cat":"3"}
};
res.JSON(data);
};
Front-end
$.getJSON('getChatData', function(data){
//...
})
I think you need to setup a route to handle the GET request that $.getJSON makes, or if getusers.js is in the /public directory, then you need to modify your $.getJSON call as follows:
$.getJSON('http://localhost:8080/public/getusers.js', function(data){
Ok, it looks like it is a problem with your getusers.js file. $.getJSON seems to prefer double quotes. Try formatting it like this:
{
"dog" : "2",
"cat" : "3"
}
Also, try using this to display the data:
$.getJSON('getusers.js', function(data){
var items = [];
$.each( data, function( key, val ) {
items.push("<li id='" + key + "'>" + val +"</li>");
});
$('#list_of_users').append(items.join(""));
});