trying to send db.collection().find() back to client with ajax request - javascript

I'm using mongoDB to get back all of my collections with:
rawData = db.collection('Forecasts').find({});
After getting the collection I want to return this via res.json() function to the client side. how can i return it.
Adding my Server side code (using Express and Node JS):
router.post('/forecastHistory', (req, res, next) => {
var rawData;
var forecasts = [];
// Connection url
var url = 'mongodb://localhost:27017/SimplyForecastDB';
// Connect using MongoClient
MongoClient.connect(process.env.MONGODB_URI || url, (err, db) => {
if (err) {
console.log('Unable to connect to MongoDB server.');
}
console.log('Connected to MongoDB server.');
rawData = db.collection('Forecasts').find({}).forEach(function(doc) {
//console.log(JSON.stringify(doc, undefined, 2));
forecasts.push(doc);
});
db.close();
});
forecasts.forEach(function(doc){
console.log(JSON.stringify(doc, undefined, 2));
});
res.json(forecasts);
});
Adding my client side code here to (using js query and ajax):
$("#history").click(function() {
$.post('/forecastHistory', function(result) {
result.forEach(function(forecast){
$("#forecast").html(
"<p class=\"lead\">" + forecast.location + "</p>" +
"The summary of today: " + forecast.summary +
"<br>" + "Temp: " + forecast.temperature + " C" +
"<br>" + "It feels like: " + forecast.feelsLike + " C" +
"<br>" + "The Humidity: " + forecast.humidity + " %" +
"<br>" + "Wind Speed: " + forecast.windSpeed + " km/h" +
"<br>"
)
});
});
});
I would appreciate the help.

As per your code, it seems like you are sending the response to the client before you get the response from MongoDB, thus the 'forecasts' variable would be essentially empty. And since you want to send an array in response, use toArray instead of forEach
router.post('/forecastHistory', (req, res, next) => {
var rawData;
var forecasts = [];
// Connection url
var url = 'mongodb://localhost:27017/SimplyForecastDB';
// Connect using MongoClient
MongoClient.connect(process.env.MONGODB_URI || url, (err, db) => {
if (err) {
console.log('Unable to connect to MongoDB server.');
}
console.log('Connected to MongoDB server.');
rawData = db.collection('Forecasts').find({}).toArray(function(err,doc) {
if(err){
console.log(err);
return;
}
res.json(doc);
res.end();
});
db.close();
});
});

Related

I am trying to retrieve data from mongodb collection using nodejs but i have to request it twice to get the correct information

This is my code:
I have to request twice to get the data. Any problem? Thanks
var http = require('http');
var url = require('url');
var input = "";
const MongoClient = require('mongodb').MongoClient;
const url2 = "mongodb+srv://ramaty01:password#cluster0-hi4fv.mongodb.net/test?retryWrites=true&w=majority";
http.createServer(function(req, res){
if (req.url === '/favicon.ico') {
res.writeHead(200, {'Content-Type': 'image/x-icon'} );
res.end();
console.log('favicon requested');
return;
}
res.writeHead(200, {'Content-Type': 'text/html'});
res.write(
"<html><head><title> MongoDB and NodeJS</title></head>" +
"<body><h1> COMPANY STOCK STICKER</h1><form>" +
"<input type='radio' id='company' name='types' value='company' required>" +
"<label for='company'>Company Name</label><br>" +
"<input type='radio' id='stock' name='types' value='stock'>" +
"<label for='stock'>Stock Ticker</label><br><br>" +
"<label for='txt'>Input: </label>" +
"<input type='text' id='txt' name='txt'><br><br>" +
"<input type='submit' value='Submit'>" +
"</form><div id='output'></div></body></html>"
);
var qobj = url.parse(req.url, true).query;
//var items;
mong(qobj);
res.write(input);
res.end()
input= "";
}).listen(8080);
function mong(qobj){
MongoClient.connect(url2, { useUnifiedTopology: true }, function(err, db) {
if(err) { console.log("Connection err: " + err); return; }
var dbo = db.db("Company");
var coll = dbo.collection('companies');
var query;
var inp = qobj.txt;
if (qobj.types == "company") {
query = { "company_name" : inp};
} else if (qobj.types == "stock") {
query = { "stock_ticker" : inp};
}
var s = coll.find(query,{projection: {"company_name":1, "stock_ticker":1, "_id":0}}).stream();
s.on("data", function(item) {input = input + item.company_name + " " + item.stock_ticker;});
s.on("end", function() {console.log("end of data"); db.close();});
});
}
First of all, I recommend that you immediately change your monogdb atlas password, and that you be more careful next time you're posting anything with sensitive information online.
With that being said, having worked with mongodb Atlas for sometime now, I've noticed that connection normally takes sometime, and that introduces some noticeable lag the fist time you fire up your server. That is probably what is happening, and since from your code I can't see evidence that your local server is waiting for this connection to happen before "serving" requests to your browser, there is no guarantee of the succession of events
To test this hypothesis, I suggest you wait for sometime before accessing the local server. This can be easily solved using an async function, or chaining a promise before starting your local server

Azure Blob Storage crashes electron app

When I am posting a picture from my electron app to blob storage, sometimes it works, and other times I get this error on my terminal:
When I was first working on this app, this problem never showed up, until a week ago. It occurred without making any changes to this part of the app. Any idea on what could cause it.
The electron app goes white, and the dev tools are disconnected.
Here is the code:
var azure = require('azure-storage');
var blobSvc = azure.createBlobService('*connection keys inside here*');
function createBlob() {
blobSvc.createContainerIfNotExists('photos', {publicAccessLevel : 'blob'}, function(error, result, response){
if(!error){
console.log(response);
}
});
console.log("creating image for student#: " + stud_id);
blobSvc.createBlockBlobFromStream('photos', stud_id + '.jpg', toStream(imgData), imgData.size, function(error, result, response){
if(!error){
console.log("file upload: \n" + JSON.stringify(result) + " \n" + JSON.stringify(response));
createPerson();
}
else if (error) {
console.log("error: " + JSON.stringify(error));
}
});
}
In your code, you actually call the createBlockBlobFromStream immediately, probably without container having created. This may cause the problem.
So, you would need to put them within the callback of the createContainerIfNotExists function:
blobSvc.createContainerIfNotExists('photos', {publicAccessLevel : 'blob'}, function(error, result, response) {
if(!error) {
console.log(response);
console.log("creating image for student#: " + stud_id);
blobSvc.createBlockBlobFromStream('photos', stud_id + '.jpg', toStream(imgData), imgData.size, function(error, result, response) {
if(!error) {
console.log("file upload: \n" + JSON.stringify(result) + " \n" + JSON.stringify(response));
createPerson();
} else {
console.log("error: " + JSON.stringify(error));
}
});
}
});

node.js: HTML form hangs after submit when inserting data into PostgreSQL database

I have recently set up node.js using Express and I created a simple HTML form using Jade. The form is to insert the data in a PostgreSQL database. The problem is that when I press submit on the form, everything is inserted on the database, but the HTML form is just hanging/lingering, and at some point it stops with No data received, ERR_EMPTY_RESPONSE. Sometimes it also inserts the data twice. I guess this is because the server side does not return a response, but I cannot see how (I am new to node.js).
The form has action="add_device" which is routed to routes/add_device.js. add_device.js looks like this:
var express = require('express');
var router = express.Router();
router.get('/', function(request, response, next) {
res.send('Nothing to see here. Move along.');
});
router.post('/', function(request, response, next) {
var db = require('../public/javascripts/db/insert');
var result = db.insertDevice(request, response);
return result;
});
module.exports = router;
The insertDevice function in my db module looks like this (it is exported with module.exports):
// Insert new QA device. Data arriving as a request from a HTML form.
insertDevice: function (request, response) {
// Input that is verified in the HTML form.
// Convert to proper format for PostgreSQL query.
var name = '\'' + request.body.name + '\'';
var ip_address = '\'' + request.body.ip_address + '\'';
var os = '\'' + request.body.os + '\'';
// Input that needs to be verified. Prepare for PostgreSQL query.
var mac_address;
var os_version;
request.body.mac_address == "" ? mac_address = 'NULL' : mac_address = '\'' + request.body.mac_address + '\'';
request.body.os_version == "" ? os_version = 'NULL' : os_version = '\'' + request.body.os_version + '\'';
var pg = require('pg'); // PostgreSQL module.
var td = require('./table_data') // Database constants.
var client = new pg.Client(request.app.get('postgreConnection'));
client.connect(function(err) {
if (err) {
return console.error('Could not connect to postgres', err);
}
var QUERY = "INSERT INTO " + td.QA_DEVICES.TABLE_NAME + "(" +
td.QA_DEVICES.COLUMN_NAME + ", " +
td.QA_DEVICES.COLUMN_MAC_ADDRESS + ", " +
td.QA_DEVICES.COLUMN_IP_ADDRESS + ", " +
td.QA_DEVICES.COLUMN_OS + ", " +
td.QA_DEVICES.COLUMN_OS_VERSION + ") VALUES(" +
name + ", " +
mac_address + ", " +
ip_address + ", " +
os + ", " +
os_version + ");";
client.query(QUERY, function (err, result) {
if (err) {
return console.error('Error running query: ' + QUERY, err);
}
console.log('Query performed: ' + QUERY);
client.end();
});
});
}
The 'Query performed' is always logged to console and data inserted into the database, but the form is still hanging. My questions are:
Is it the lack of response from the server that makes the form hang?
How can I "send a response back" to the front end?
Is it possible to route the front end to another page after insertion into the database? What is the best practice?
Yes, your request is receiving no response, so it is hanging.
In order to send a response, you can either send a blind acknowledgement right when the request is received (that is not dependent upon the success of the query and may be bad practice), or you can send it in the callback.
client.query(QUERY, function (err, result) {
if (err) {
// response.json({status: 'error'});
response.write('Error');
return console.error('Error running query: ' + QUERY, err);
} else {
// You can send json here too
// response.json({status: 'success'});
response.write('Success');
}
console.log('Query performed: ' + QUERY);
client.end();
});
If you want to go to another page, simply parse the incoming response on the client side and do a redirect. Using json is a good way to carry this out. You can also do a response.redirect(url) on the server side too, instead of sending back data. Have fun

How do I work with query results - Javascript (Azure Database)

so I am using Microsoft Visual Studio 2013 with Apache Cordova at the moment and using Microsoft Azure as the backend database (New to this!). I have written the following code as a test and I can't seem to work with the results of a query. alert(JSON.stringify(results)) seems to work and is alerting the query results as [{"id":"1234","username":"james","password":"james"}]. However, when I try to use results.length or results.'anything', it is not recognising results as an array. Is there a way I can work with the query results? Help is much appreciated :)
function test() {
//Query the Accounts table where the input fields match a record in the table.
var query = accountsTable.where({
username: textUsername.value,
password: textPassword.value
}).read().done(function (results) {
alert(JSON.stringify(results));
var queryTest = results[0].text;
}, function (err) {
alert("Error: " + err);
});
}
You need to specify property name, it seems you are specifying the text, which is not there.
For single record:
var query = accountsTable.where({
username: textUsername.value,
password: textPassword.value
}).read().done(function (results) {
alert(results[0].id + " " + results[0].username + " " + results[0].password);
}, function (err) {
alert("Error: " + err);
});
For multiple records:
var query = accountsTable.where({
username: textUsername.value,
password: textPassword.value
}).read().done(function (results) {
for (var i = 0; i < results.length; i++) {
alert(results[i].id + " " + results[i].username + " " + results[i].password);
}
}, function (err) {
alert("Error: " + err);
});

How to get asynchronous data using nodejs

I am attempting to get data from a mysql table using nodejs. I call the sql routine which is in another node js file. However, I cannot get my callback to return the data. I think the problem might be that I am calling an asynchronous routine from a node js file rather than from an angular or regular javascript program. Below is the exports script I am calling.
exports.getVenueById = function(db, id) {
var http = require('http');
var mysql = require('mysql');
var query = "SELECT * FROM venues WHERE auto_increment = ? "
query = mysql.format(query, id);
console.log("query=" + query);
db.query(
query,
function(err, rows) {
if(err) console.log("error=" + err);
console.log("rows=" + rows[0]['auto_increment']);
res.json({success: true, response: rows});
//return rows[0];
});
}
I know this is working because I am writing the results to the console. The problem is the data never gets back to the calling node js routine below.
function getVenueData (id , callback) {
(function () {
venueData = venueTable.getVenueById(db, id);
if(venueData) {
callback();
console.log("callback in loop");
}
console.log("callback after loop");
});
}
getVenueData(id, gotVenueData);
The program immediately returns and displays the timeout message. I admit that I am not an expert in nodejs or its callback feature. I would appreciate any feedback as to how I can get the program to wait for the asynchronous data to return to the calling program.
function gotVenueData() {
console.log("gotVenueData");
}
setTimeout(function() { console.log("timeout for 10 seconds");} , 10000);
console.log("venuedata=" + venueData);
You're trying to return async data syncronously. Instead, add a callback to getVenueById:
exports.getVenueById = function (db, id, cb) {
var http = require('http');
var mysql = require('mysql');
var query = "SELECT * FROM venues WHERE auto_increment = ? ";
query = mysql.format(query, id);
console.log("query=" + query);
db.query(
query,
function (err, rows) {
if (err) console.log("error=" + err);
console.log("rows=" + rows[0]['auto_increment']);
cb({
success: true,
response: rows
});
// return rows[0];
});
and use it as such:
venueTable.getVenueById(db, id, function(data) {
console.log(data);
});
One caveat: Traditionally the callback has the first parameter as the error (or null) and then the actual data. With that in mind:
exports.getVenueById = function (db, id, cb) {
var http = require('http');
var mysql = require('mysql');
var query = "SELECT * FROM venues WHERE auto_increment = ? ";
query = mysql.format(query, id);
console.log("query=" + query);
db.query(
query,
function (err, rows) {
if (err) { cb(err); }
console.log("rows=" + rows[0]['auto_increment']);
cb(null, {
success: true,
response: rows
});
// return rows[0];
});
and use it as such:
venueTable.getVenueById(db, id, function(err, data) {
if (err) { return console.log(err); }
console.log(data);
});

Categories