I am trying to use node.js to provide json results from MongoDB.
var http = require('http');
var mongo = require('mongoskin');
http.createServer(function (req, res) {
var args = req.url.split("/");
console.log(args);
var searchCollection = args[1];
var searchVar = args[2];
var searchString = args[3];
var conn = mongo.db('user:pass#alex.mongohq.com:10039/name',{safe:true});
conn.collection(searchCollection).find({searchVar:searchString}).toArray(function(err, items){
if(err) throw err;
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end(JSON.stringify(items));
});
}).listen(process.env.PORT, process.env.IP);
The problem I am having is when I call the find function on the database it:-
searches for a document with a variable 'searchVar'
rather than searching for a variable with the value of the searchVar
Any help would be appreciated. Thanks!
You will need to create your query object something like this:
var query = {};
query[searchVar] = searchString;
And then pass this into your query:
conn.collection(searchCollection).find(query).toArray(function(err, items){
if(err) throw err;
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end(JSON.stringify(items));
});
Related
I'm trying out the code basics and want to write some basic client-server app.
I have an HTML page where user inputs two numbers (num1 and num2) then it passes to JS which passes it to HTTP server written with NodeJS. On the server the numbers should be added and returned to the HTML page. But the server returns this error:
ReferenceError: num1 is not defined
What is wrong with the code?
Here is the JS code:
function myFunction(num1, num2) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
num1 = Math.floor(num1);
num2 = Math.floor(num2);
document.getElementById("result").innerHTML = this.responseText;
}
};
xhttp.open("GET", "http://localhost:8080?num1=2&num2=3", true);
xhttp.send();
}
And here is the NodeJS code:
var http = require('http');
http.createServer(function (req, res) {
var resnum = 2 + req.params(num1) + req.params(num2);
res.writeHead(200, {'Content-Type': 'text/html'});
res.write(resnum);
res.end();
}).listen(8080);
You have to use the url module https://nodejs.org/api/http.html#http_message_url
var http = require('http');
var url = require('url');
http.createServer(function (req, res) {
var params = url.parse(req.url, true).query;
var resnum = 2 + params.num1 + params.num2; //or 2 + parseInt(params.num1) + parseInt(params.num2)
res.writeHead(200, {'Content-Type': 'text/html'});
res.write(resnum);
res.end();
}).listen(8080);
If you want a concise code like yours you need to use some module like Express framework.
var express = require('express')
var app = express()
app.get('/', function (req, res) {
const resnum = 2 + parseInt(req.query.num1) + parseInt(req.query.num2);
res.writeHead(200, {'Content-Type': 'text/html'});
res.end(resnum.toString())
})
app.listen(8080)
When you are using 'http' module only, the only thing you have to work with is req.url. You could try hard and get the parameters by breaking down the url but you would have a lengthy code:
var http = require('http');
http.createServer(function (req, res) {
const step1 = req.url.split('?')[1] //step1 = num1=2&num2=3
const step2 = step1.split('&') // step2 = [num1=2,num2=3]
let result = {};
step2.forEach((val) => { //break down strings further and put into result object
const value = val.split('=')
result[value[0]] = value[1]
})
var resnum = 2 + parseInt(result.num1) + parseInt(result.num2);
res.writeHead(200, {'Content-Type': 'text/html'});
res.end(resnum.toString());
}).listen(8080);
Some notes:
You get that error because num1 is a variable argument to a
function. However we don't have a variable num1 declared.
Parameters come as strings so unless you parse them into integers,
you will have string concatenation and 223 as a result
res.write and res.end need a
string input so you need to parse back to string after calculations.
I'm working on an app that takes a list of latitudes and longitudes from a mongodb database and puts them onto a google map as points, but I'm having an issue parsing the JSON that is outputted by mongoose from node.js, here's the code I'm using to parse the JSON. The error that the browser is giving me is:
SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data
var jsonData = JSON.parse('http://hanky-ranky.azurewebsites.net/listbathroom');
for (var i = 0; i < jsonData.length; i++) {
var bathroom = jsonData[i];
console.log(bathroom.lat);
}
Here's the code I used to generate the JSON inside of node.js using mongoose
var express = require('express');
var router = express.Router();
var mongoose= require("mongoose");
//Connect to mongo DB
mongoose.connect('mongodb://test:test#ds040898.mongolab.com:40898/MongoLab-0');
var myDB = mongoose.connection;
//Error handling if conncetion fails
myDB.on('error', console.error.bind(console, 'connection error:'));
//Check if successful connection is made
myDB.once('open', function callback () {
//console.log("MY DB Connected with Mongoose");
});
//create an employee schema for operation with mongo
var bathroomSchema = mongoose.Schema(
{
'name': String,
'address' : String,
'lat': String,
'lng': String,
'type': String,
},
{
collection:'bathrooms'
}
);
// model reference
var bathrooms = mongoose.model('bathrooms', bathroomSchema);
function readBathrooms(callback)
{
bathrooms.find({},function (error, result) {
callback(error, result);
});
}
router.get('/', function(req, res, next) {
readBathrooms(function(error,result){
if (error) {
res.send({'result':'error'});
console.log("Error!");
}else {
//console.log(result);
res.render('listbathroom', {"result": result });
}
});
});
module.exports = router;
And here's the jade file that is called for displaying the JSON
!{result}
As Kevin B pointed out to me, I wasn't actually parsing JSON, but instead was attempting to parse a URL as JSON. I solved my problem with the following code
var xmlhttp = new XMLHttpRequest();
var url = "http://hanky-ranky.azurewebsites.net/listbathroom";
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var thejson = JSON.parse(xmlhttp.responseText);
logjson(thejson);
}
}
xmlhttp.open("GET", url, true);
xmlhttp.send();
function logjson(arr) {
var i;
for(i = 0; i < arr.length; i++) {
console.log(arr[i].lat);
}
}
I am newbie in Nodejs world. I am trying to insert data in MongoDB using Mongoose. The idea is
- I will have a server running on node
- any incoming POST data will be saved in Mongo.
The problem when the below code is run no data gets saved in MongoDB and also no error is shown. Am i missing something here. Any help will be really appreciated.
I have the below code that writes data in mongoDB for an incoming http request.
var http = require('http') // http module
, fs = require('fs') // file system module
, qs = require('querystring') // querystring parser
, mongoose = require('mongoose');
mongoose.connect("mongodb://localhost/app_data_db");
var db = mongoose.connection;
var appDataSchema = new mongoose.Schema({
record_id: Number,
app_version: Number,
imei: String,
created_time: Date,
device_uid: String,
model: String
});
var appDataModel = mongoose.model("app_data_collection",appDataSchema);
var PORT=8080;
http.createServer(function(req,res){
if(req.method == "POST") {
var POST = {};
//parse query string
req.on('data', function(data) {
data = data.toString();
data = data.split('&');
for (var i = 0; i < data.length; i++) {
var _data = data[i].split("=");
POST[_data[0]] = _data[1];
}
db.once('open', function (callback) {
appDataModel.create({
record_id: POST["id"],
app_version: POST["app_version"],
imei: POST["imei"],
created_time: new Date((parseInt(POST["created_time"]) + 19800) *1000), // to set correct time zone IST
device_uid: POST["device_uid"],
model: POST["model"]
});
});
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('saved to DB:'+POST["id"]+'\n');
console.log('saved to DB:'+POST["id"]+'\n');
});
mongoose.disconnect();
}
}).listen(PORT);
To test this I am manually firing this curl call:
curl -X POST --data "id=58648148&app_version=4.8&imei=355886053224492&created_time=1417372202&device_uid=e385c8a5a4c01304&model=GT-I9082" http://localhost:8080
There are couple problems with your code:
1) you call mongoose.disconnect outside of the callback, which means that it's called before the callback is executed
2) you're creating the model inside the callback, but sending the response outside of it, so the response is sent before the model is created
3) and finally create method provides a callback when the entity is saved to the db, which you don't use it all
Here's the modified code:
mongoose.connect("mongodb://localhost/app_data_db");
db.on('open', function() {
http.createServer(function(req, res) {
if(req.method == "POST") {
var POST = {};
//parse query string
req.on('data', function(data) {
data = data.toString();
data = data.split('&');
for (var i = 0; i < data.length; i++) {
var _data = data[i].split("=");
POST[_data[0]] = _data[1];
}
appDataModel.create({
record_id: POST["id"],
app_version: POST["app_version"],
imei: POST["imei"],
created_time: new Date((parseInt(POST["created_time"]) + 19800) *1000), // to set correct time zone IST
device_uid: POST["device_uid"],
model: POST["model"]
},
function(err){
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('saved to DB:'+POST["id"]+'\n');
console.log('saved to DB:'+POST["id"]+'\n');
mongoose.disconnect();
});
});
}
}).listen(PORT);
});
I think I got this working. I have moved the mongoose connection inside. Rest all is same. Since I wanted to post the code hence answering instead of commenting. This may help others. Here is the complete code
var http = require('http') // http module
, fs = require('fs') // file system module
, qs = require('querystring') // querystring parser
, mongoose = require('mongoose');
var appDataSchema = new mongoose.Schema({
record_id: Number,
app_version: Number,
imei: String,
created_time: Date,
device_uid: String,
model: String
});
var appDataModel = mongoose.model("app_data_collection", appDataSchema);
var PORT = 8080;
http.createServer(function(req, res) {
if (req.method == "POST") {
var POST = {};
//parse query string
req.on('data', function(data) {
data = data.toString();
data = data.split('&');
for (var i = 0; i < data.length; i++) {
var _data = data[i].split("=");
POST[_data[0]] = _data[1];
}
mongoose.connect("mongodb://localhost/app_data_db");
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function() {
appDataModel.create({
record_id: POST["id"],
app_version: POST["app_version"],
imei: POST["imei"],
created_time: new Date((parseInt(POST["created_time"]) + 19800) * 1000), // to set correct time zone IST
device_uid: POST["device_uid"],
model: POST["model"]
}, function(err) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('saved to DB:' + POST["id"] + '\n');
console.log('saved to DB:' + POST["id"] + '\n');
mongoose.disconnect();
});
});
});
}
}).listen(PORT);
I have a file called node.js:
var net = require('net');
var crypto = require('crypto');
//sjcl
var sjcl = require('./sjcl');
//retrive fb profile
var loadFb = require('./loadFb.js');
var loadFeed = require('./loadFeed.js');
//read json user file
var fs = require('fs');
var text = fs.readFileSync(__dirname + '/users','utf8');
var HOST = 'localhost';
var PORT = 7000;
net.createServer(function(sock) {
// We have a connection - a socket object
console.log('CONNECTED: ' + sock.remoteAddress +':'+ sock.remotePort);
// Add a 'data' event handler to this instance of socket
sock.on('data', function(data) {
console.log('User request profile of: ' + data);
//var date = (data.toString()).split("***");
//var from = date[1];
loadFb(extendetPath, function(pageData)
{
loadFeed(extendetPath2, function(pageData2)
{
var fs = require('fs');
var profileText = fs.readFileSync('/tmp/profile','utf8');
console.log(profileText);
sock.write(profileText);
});
});
});
// Add a 'close' event handler to this instance of socket
sock.on('close', function(data) {
console.log('CLOSED: ' + sock.remoteAddress +' '+ sock.remotePort);
});
}).listen(PORT);
console.log('Server listening on ' + HOST +':'+ PORT);
function returnKeyFromUser(id)
{
//text
var trovata = false;
var dati = JSON.parse(text);
for(var i=0; i<dati.friendlist.friend.length && trovata==false; i++)
{
var user = (dati.friendlist.friend[i].username).replace("\n","");
var userID = (id).replace("\n","");
if(user==userID)
{
trovata=true;
return ((dati.friendlist.friend[i].publicKey).toString()).replace("\n","");
}
}
if(trovata==false)
return null;
}
There is a small http server that receives a facebook username and what he have to do is retrieve 2 page:
a graphapi with the profile information, and a graphapi with the feed informations of a facebook profile
I copy the other two files:
var https = require('https');
module.exports = function(path, callback) {
var options = {
host: 'graph.facebook.com',
port: 443,
path: (path.toString()).replace("\n",""),
method: 'GET'
};
var req = https.get(options, function(res) {
var pageData = "";
if((path.toString()).indexOf("/")==0 && (path.toString()).indexOf("/GET /`HTTP/")!=0)
//for load only (I hope facebook profile)
{
console.log(options);
res.setEncoding('utf8');
res.on('data', function (chunk) {
pageData += chunk;
});
res.on('end', function()
{
var fs = require('fs');
fs.writeFile("/tmp/profile", pageData, function(err) {
if(err) {
console.log(err);
} else {
console.log("The file was saved!");
}
});
//callback(pageData);
return;
});
}
});
};
3° file
var https = require('https');
module.exports = function(path, callback) {
var options = {
host: 'graph.facebook.com',
port: 443,
path: (path.toString()).replace("\n",""),
method: 'GET'
};
var req = https.get(options, function(res) {
var pageData = "";
if((path.toString()).indexOf("/")==0 && (path.toString()).indexOf("/GET / HTTP/")!=0) //for load only (I hope facebook profile)
{
console.log(options);
res.setEncoding('utf8');
res.on('data', function (chunk) {
pageData += chunk;
});
res.on('end', function()
{
var fs = require('fs');
fs.appendFile('/tmp/profile', "***"+pageData, function (err) {
if (err) throw err;
console.log('It\'s saved!');
});
callback(pageData);
});
}
});
};
I don't know If there is a way to call the two file in the first file node.js but what I done is this: (to call from node.js the fist file, and from the second file call the third)
in node.js file I call the first file loadFb.js with this command:
loadFb(extendetPath, function(pageData)
{
This call saves a file on my tmp profile directory and inside I call the other file loadFeed that appends some text.
After that I have to send the entire information to the client but I have a mistake.
In order the nodejs correctly call loadFb and he write tmp - profile, than he call loadFeed
but before appending the information the node call back to the client only the half of informations that I need.
I'm not a good nodejs programmer, this is a work for my thesis.
Can someone help me?
Let's look at the following code:
res.on('end', function()
{
var fs = require('fs');
fs.appendFile('/tmp/profile', "***"+pageData, function (err) {
if (err) throw err;
console.log('It\'s saved!');
});
callback(pageData);
});
What it does it runs the asynchronous method appendFile and immediately after that calls callback. So when the code in the callback is executed, the file is not updated yet. You need to move the callback(pageData); to the appendFile's callback. And you need to review you code keeping this in mind because I see that the same fix should be made in another file so maybe there are some similar places as well.
I'm tryign to build a very simple scraper function for nodeJS - just a function that I can pass a URL to, and it returns the scraped data as var data.
I'm completely new to Node.js and can't work out why the following isn't working:
var request = require('request');
var cheerio = require('cheerio');
function scrape(url) {
console.log("Scraping: " + url);
request(url, function(err, resp, body) {
if (err) {
throw err;
}
var html = cheerio.load(body);
return html;
});
}
var data = scrape('http://www.stackoverflow.com');
$ = data;
var logo = $('#hlogo a').text();
console.log(logo);
The above code should return "Stack Overflow" but obviously does not. When I run this in the console I get an error:
var logo = $('#hlogo a').text();
^
TypeError: Property '$' of object #<Object> is not a function
Any ideas why this isn't working for me?
Your data will be undefined, because scrape function does not return a value, additionaly it asynchronous.
You need change logic to something like this:
function scrape(url, oncomplete) {
console.log("Scraping: " + url);
request(url, function(err, resp, body) {
if (err) {
throw err;
}
var html = cheerio.load(body);
oncomplete(html);
});
}
scrape('http://www.stackoverflow.com', function(data) { /* do work here*/ });