I struggle while trying to do a simple mongoDB query from within my express app:
app.js
var express = require('express');
var routes = require('./routes');
var user = require('./routes/user');
var http = require('http');
var path = require('path');
var mongourl = ''; // omitted on SO
var MongoClient = require('mongodb').MongoClient;
var dbInstance;
MongoClient.connect(mongourl, function(err, db) {
db.on('open',function(){
dbInstance = db;
})
});
app.get('/', routes.index(dbInstance));
http.createServer(app).listen(app.get('port'), function(){
});
routes/index.js
exports.index = function(db){
return function(req,res){
}
};
Do i understand correctly that the exports.index' paramter is a database instance? If so, why can't i do db.getCollectionNames()?
How would i work with the database instance in my route?
node.js is asynchronous. This means that db and so dbInstance do not exist after the Mongoclient.connect() function call, but within the callback. So your code has to look like:
MongoClient.connect(mongourl, function(err, db) {
...
app.get( '/', routes.index( db ) );
...
});
Related
I am trying to fetch data from database but stuck at a point. I am getting this error but I don't know what is going wrong. I have try to find the solution
but still not getting appropriate answer. I am trying to implement it from this tutorial.
https://www.fusioncharts.com/dev/using-with-server-side-languages/tutorials/creating-interactive-charts-using-node-express-and-mongodb
Here is my code:
//import express package
var express = require("express");
//import mongodb package
var mongodb = require("mongodb");
//MongoDB connection URL - mongodb://host:port/dbName
var dbHost = "mongodb://localhost:27017/fusion_demo";
//DB Object
var dbObject;
//get instance of MongoClient to establish connection
var MongoClient = mongodb.MongoClient;
//Connecting to the Mongodb instance.
//Make sure your mongodb daemon mongod is running on port 27017 on localhost
MongoClient.connect(dbHost, function(err, db){
if ( err ) throw err;
dbObject = db;
console.log('connect to server');
// console.log(db);
});
function getData(responseObj){
//use the find() API and pass an empty query object to retrieve all records
dbObject.collection("fuel_price").find({}).toArray(function(err, docs){
if ( err ) throw err;
var monthArray = [];
var petrolPrices = [];
var dieselPrices = [];
for ( index in docs){
var doc = docs[index];
//category array
var month = doc['month'];
//series 1 values array
var petrol = doc['petrol'];
//series 2 values array
var diesel = doc['diesel'];
monthArray.push({"label": month});
petrolPrices.push({"value" : petrol});
dieselPrices.push({"value" : diesel});
}
var dataset = [
{
"seriesname" : "Petrol Price",
"data" : petrolPrices
},
{
"seriesname" : "Diesel Price",
"data": dieselPrices
}
];
var response = {
"dataset" : dataset,
"categories" : monthArray
};
responseObj.json(response);
});
}
//create express app
var app = express();
//NPM Module to integrate Handlerbars UI template engine with Express
var exphbs = require('express-handlebars');
//Declaring Express to use Handlerbars template engine with main.handlebars as
//the default layout
app.engine('handlebars', exphbs({defaultLayout: 'main'}));
app.set('view engine', 'handlebars');
//Defining middleware to serve static files
app.use('/public', express.static('public'));
app.get("/fuelPrices", function(req, res){
getData(res);
});
app.get("/", function(req, res){
res.render("chart");
});
app.listen("3300", function(){
console.log('Server up: http://localhost:3300');
});
dbObject is null hence doesn't have the collection method. Probably Mongo DB is not running or is running in a different port. Check MongoDB is correctly up and running and you can connect to it.
I am making an app where the app is going to send the POST request data to the nodeJS server. The JSON format of the content looks like: {"encrypteddata": "someencryptedvalueofthetext"}. This data will be saved in a MongoDB.
I created two file one is app.js and another is /models/encdata.js. Content of both the file is given below.
app.js
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
app.use(bodyParser.json());
ENCDATA = require('./models/encdata');
mongoose.connect('mongodb://localhost/encdata', { useMongoClient: true }); // the url access the database
var db = mongoose.connection;
app.get('/', function(req, res){
res.send('Visit /api/encdata');
app.get('/api/encdata', function(req, res){
ENCDATA.getENCDATA(function(err, encdata){
if(err){
throw err;
}
res.json(encdata);
});
});
app.post('/api/encdata', function(req, res){
var encdata = req.body;
ENCDATA.addENCDATA(encdata, function(err, encdata){
if(err){
throw err;
}
res.json(encdata);
});
});
});
app.listen(3000);
console.log('Running on port 3000');
encdata.js
var mongoose = require('mongoose');
var encdataencryptSchema = mongoose.Schema({
encrypteddata: {
type: String,
required: true
}
});
var ENCDATA = module.exports = mongoose.model('encdata', encdataencryptSchema);
module.exports.getENCDATA = function(callback, limit){
ENCDATA.find(callback).limit(limit);
}
module.exports.addENCDATA = function(encdata, callback){
ENCDATA.create(encdata, callback);
}
And data in MongoDB is:
{"encrypteddata": "someencryptedvalueofthetext"}
But when I make a GET request to the url localhost:3000/api/encdata it shows [] (an empty array although I have data). Even the POST request is not working and I am not able to save any data.
I rewrote your code by changing the name of the variable and it worked for me. The app.js file looks something like this:
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
var http = require('http');
app.use(bodyParser.json());
AES = require('./models/aes');
mongoose.connect('mongodb://localhost/aes', { useMongoClient: true }); // the url access the database
var db = mongoose.connection;
app.get('/', function(req, res){
res.send('Visit /api/aes');
app.get('/api/aes', function(req, res){
AES.getAES(function(err, aes){
if(err){
throw err;
}
res.json(aes);
});
});
app.post('/api/aes', function(req, res){
var aes = req.body;
AES.addAES(aes, function(err, aes){
if(err){
throw err;
}
res.json(aes);
});
});
});
app.listen(3000);
console.log('Running on port 3000');
In the encdata.js you can change the variable to AES. Name the mongodb collection and database as aes.
I am trying to get a number that will be stored in short variable. Then I look up on the database for a specific shortUrl that matches that number. If I find it I want the response to be the full url, let's suppose www.google.com.
So when the user type, for instance: localhost:8888/3451 that would redirect to www.google.com.br
app.get('/:short', function(req, res){
var short = req.params.short;
shortUrl.find({shortUrl: short}).then(function(result){
var urlSearch = result[0]["url"]; //www.google.com
res.redirect(urlSearch) //DOESNT WORK
});
});
How can I do this?
Try this code.This works like charm!!!!!!.
Firsrt create a models folder and place this file in it shortUrl.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var Url = new Schema({
shortUrl:
{
type : Number
},
url:
{
type : String
}
});
module.exports = mongoose.model('url', Url);
Next create a routes folder place this file in it urls.js
var express = require('express');
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
var shortUrl = require('../models/shortUrl');
var app = express();
var url = express.Router();
url.use(bodyParser.json());
url.route('/:short')
.get( function(req, res){
var short = req.params.short;
shortUrl.find({shortUrl: short}).then(function(result){
var urlSearch = result[0]["url"];
res.redirect('https://'+urlSearch) //DOESNT WORK
});
});
url.route('/num')
.post(function(req,res){
shortUrl.create(req.body,function(err,url){
if (err) return console.log(error);
return res.send(url);
});
})
app.use('/url',url);
module.exports = url;
Next create a config file so that you can give connections config.js
module.exports = {
'secretKey': '12345-67890-09876-54321',
'mongoUrl' : 'mongodb://localhost:27017/redirect'
}
And now create a server file like express.js
var express = require('express');
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var config = require('./config');
var mongoose = require('mongoose');
mongoose.Promise = require('bluebird');
mongoose.connect(config.mongoUrl);
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function () {
console.log("Connected correctly to server");
});
var app = express();
var url = require('./routes/url');
var shortUrl = require('./models/shortUrl');
app.use('/url',url);
app.listen(3000,function(){
console.log("Server listening on port 3000");
});
Output : Run the code as node express.js
Whenever you want to post use http://localhost:3000/url/num and give the details in json format.Whenever you want to get i.e.,redirect to aany page use http://localhost:3000/url/:shrot.Here :short nothing but a number should be passed a parameter.Hope this helps for you.
Try this solution
res.writeHead(301,
{Location: 'http://whateverhostthiswillbe.com'}
);
res.end();
I am pretty new with node.js and express so bear with me please.
I am wondering how i can get a mysql instance and use it in my controller. I have 4 files that look like this:
see my comment in the controller.js file
server.js :
var express = require('./config/express');
var app = express();
module.exports = app;
app.listen(3000);
console.log('server running');
express.js :
var express = require('express'),
bodyParser = require('body-parser'),
mysql = require('mysql');
module.exports = function() {
var app = express();
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(bodyParser.json());
app.set('views','./app/views');
app.set('view engine','ejs');
//NOT SURE WHAT TO DO HERE OR WHERE TO PUT THE CONNECTION DETAILS
var dbConnection = mysql.createConnection({
host : 'localhost',
user : 'someuser',
database : 'somedb',
password : 'somepass'
});
//connection.connect();
//
//connection.query('SELECT 1 + 1 AS solution', function(err, rows, fields) {
// if (err) throw err;
// console.log('The solution is: ', rows[0].solution);
//});
//
//connection.end();
require('../app/routes/index.server.routes.js')(app);
app.use(express.static('./public'));
return app;
};
routes.js :
module.exports = function(app) {
var index = require('../controllers/index.server.controller');
app.get('/', index.render);
app.post('/', index.stuff);
};
controller.js :
exports.render = function(req, res) {
//DO DB STUFF HERE
res.render('index', {
title: 'this is the title'
});
};
exports.stuff = function(req, res) {
res.render('index', {
title: 'this is the title post'
});
};
To use the connection instance in your controller, you'll need to pass it from the express.js file to the controller.js file. The first step is to pass the connection instance to the router:
express.js
require('../app/routes/index.server.routes.js')(app, connection);
This will make it available in the routes.js file. You then need to pass the same connection instance to the controller.
index.server.routes.js
module.exports = function(app, connection) {
var index = require('../controllers/index.server.controller')(connection);
app.get('/', index.render);
app.post('/', index.stuff);
};
The controller will need to be refactored so it takes a connection instance as an argument:
index.server.controller.js
function IndexController(connection) {
controllerMethods = {};
controllerMethods.render = function (req, res) {
// You can use the connection instance here.
connection.connect()
// Run your query
connection.end()
...
};
// Define other methods for the controller
// Return the object that holds the methods.
return controllerMethods;
}
module.exports = IndexController;
I have loads of router.get functions in my code which I think, could be reduced to a single switch-case function. Here is what I have tried:
function handlerA(req, res) {}
function handlerB(req, res) {}
var routes = {
'/url-one': handlerA,
'/url-two': handlerB
}
router.get('/*', function(req, res) {
var url = req.url;
if (routes[url]) {
routes[url](req, res);
}
});
This works but also, significantly slows my application. Is there any other solution which would not hit the performance of my app?
Thanks
Is there a reason you don't want to use router.get functions? I would guess express.js is internally performing the same logic that you are doing anyway. You are just replacing get functions with handlers.
If you are using similar logic between multiple routes, that may be worth abstracting.
I usually go with a setup like this:
app.js
routes.js
api/
user/
index.js
user.controller.js
user.model.js
image/
index.js
image.controller.js
image.model.js
/api/user/index.js:
var express = require('express');
var controller = require('./user.controller');
var router = express.Router();
router.get('/', controller.index);
router.post('/', controller.create);
module.exports = router;
/api/user/user.controller.js:
var User = require('./user.model');
exports.index = function(req, res) {
// Show list of users
};
exports.create = function (req, res, next) {
// Create user
};
/routes.js:
module.exports = function(app) {
// Insert routes below
app.use('/api/users', require('./api/user'));
app.use('/api/images', require('./api/image'));
// All undefined asset or api routes should return a 404
app.route('/:url(api|auth|components|app|bower_components|assets)/*')
.get(errors[404]);
// All other routes should redirect to the index.html
app.route('/*')
.get(function(req, res) {
res.sendfile(app.get('appPath') + '/index.html');
});
};
And lastly, the /app.js:
// Set default node environment to development
process.env.NODE_ENV = process.env.NODE_ENV || 'development';
var express = require('express');
var mongoose = require('mongoose');
var config = require('./config/environment');
// Connect to database
mongoose.connect(config.mongo.uri, config.mongo.options);
// Populate DB with sample data
if(config.seedDB) { require('./config/seed'); }
// Setup server
var app = express();
var server = require('http').createServer(app);
require('./config/express')(app);
require('./routes')(app);
// Start server
server.listen(config.port, config.ip, function () {
console.log('Express server listening on %d, in %s mode', config.port, app.get('env'));
});
// Expose app
exports = module.exports = app;
Most of this is directly from the Yeoman Generator Angular-Fullstack and it has a really nice setup!