I have a Express server resolving GET /companies/:id/populate/. Now, I would like to setup GET /companies/populate/ (without the :id). However, I can't make this route to work. If I try, for example, GET /companies/all/populate/, it works, so it seems the pattern for an Express route is path/:key/path/:key.
Is this true? Thanks!
Edit: Adding code.
server.js
'use strict';
var express = require('express');
var mongoose = require('mongoose');
var bodyParser = require('body-parser');
var cors = require('cors');
var mongoUri = 'mongodb://localhost:27017';
mongoose.connect(mongoUri);
var db = mongoose.connection;
db.on('error', function() {
throw new Error('Unable to connect to database at' + mongoUri);
});
// runs Express
var app = express();
// uses Cors
app.use(cors());
// uses bodyParser
app.use(bodyParser.json());
// requires Mongo models
require('./models');
// includes routes.js, passing the object 'app'
require('./routes')(app);
// listens for connections on port 3000
app.listen(3000, function() {
console.log("Express started on Port 3000");
});
routes.js
module.exports = function(app) {
// thumbs up if everything is working
app.get('/', function(req, res, next) {
res.send('👍');
console.log('Server Running');
res.end();
});
// companies
var companies = require('./controllers/companies');
app.get('/companies', companies.findAll);
app.get('/companies/:id', companies.findById);
app.get('/companies/:id/populate', companies.populate);
app.get('/companies/populate', companies.populateAll);
app.post('/companies', companies.add);
app.patch('/companies/:id', companies.patch);
app.delete('/companies/:id', companies.delete);
};
/controllers/companies.js
var mongoose = require('mongoose');
Company = mongoose.model('Company');
// GET /companies
// status: works, needs error handling
exports.findAll = function(req, res) {
Company.find({}, function(err, results) {
return res.send(results);
});
};
// GET /companies/:id
// status: works, needs to check error handling
exports.findById = function(req, res) {
var id = req.params.id;
Company.findById(id, function(err, results) {
if (results) res.send(results);
else res.send(204);
});
};
// POST /companies
// status: works, needs error handling
exports.add = function(req, res) {
Company.create(req.body, function(err, results) {
if (err) {
return console.log(err)
} else {
console.log('company created');
}
return res.send(results);
});
};
// PATCH /companies/:id
// status: works, needs error handling
exports.patch = function(req, res) {
var id = req.params.id;
var data = req.body;
Company.update( { '_id' : id }, data, function(err, numAffected) {
if (err) return console.log(err);
return res.send(200);
});
};
// DELETE /companies/:id
// status: works, needs error handling, make sure that we are sending a 204 error on delete
exports.delete = function(req, res) {
var id = req.params.id;
Company.remove({ '_id': id }, function(results) {
console.log('deleted ' + id); // tester
return res.send(results);
});
};
// GET /companies/:id/populate
exports.populate = function(req, res) {
var id = req.params.id;
Company
.findOne({ _id: id })
.populate('contacts country')
.exec(function (err, results) {
if (err) return handleError(err);
else res.send(results);
});
};
// GET /companies/populate
exports.populateAll = function(req, res) {
Company
.find({})
.populate('contacts country')
.exec(function (err, results) {
if (err) return handleError(err);
else res.send(results);
});
};
Related
I am trying to request data from a postgres database in node.js via a post request. Eventually this data will be sent a react frontend.
I am getting correct data from database but can't seem to return this data to app.js (I'm a bit of a node.js noob). I have two files app.js and db.js
Here is app.js
const express = require('express');
const morgan = require('morgan');
const helmet = require('helmet');
const cors = require('cors')
const db = require('./db')
const bodyParser = require('body-parser')
const middlewares = require('./middlewares');
const app = express();
app.use(cors());
app.use(morgan('dev'));
app.use(helmet());
// Parse URL-encoded bodies (as sent by HTML forms)
app.use(bodyParser.urlencoded({ extended: false }))
// Parse JSON bodies (as sent by API clients)
app.use(express.json());
app.use((req, res, next) => {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
next();
});
app.get('/api', (req, res) => {
res.send({ express: 'Server online' });
});
app.post('/layer', (req, res, next) => {
var layer = req.body.menu;
var geometry = db.layer(layer);
console.log(geometry);
res.set('Content-Type', 'application/json')
//const body = res.body()
});
app.use(middlewares.notFound);
app.use(middlewares.errorHandler);
module.exports = app;
Here is db,js
const { Pool, Client } = require('pg')
const connection = new Pool({
user: 'postgres',
host: 'localhost',
database: 'dbtemp',
password: 'password',
port: 5432,
max: 20,
connectionTimeoutMillis: 2000,
})
connection.connect(function(err) {
if (err) throw err;
});
connection.on('connect', () => {
console.log("connected to database on port: " );
});
module.exports = {
layer: function(layer) {
connection.query('SELECT ST_AsGeoJSON(geom) FROM nzta_centrelines', (err, result) => {
if (err) {
return console.error('Error executing query', err.stack)
}
var geometry = result.rows[0].st_asgeojson;
console.log(geometry);
return result;
})
}
}
I am getting the correct data logged to console from db.js
Output:
Listening: http://localhost:5000
connected to database on port:
Promise { undefined }
connected to database on port:
{"type":"MultiLineString","coordinates":[[[1797202.15,5753380.18,0],[1797200.87,5753384.48,0],[1797198.16,5753393.62,0],[1797197.78,5753404.37,0],[1797200.38,5753428.48,0],[1797217.82,5753566.48,0],[1797225.98,5753623.6,0],[1797227.09,5753645.86,0],[1797225.98,5753665.52,0],[1797223.38,5753684.07,0],[1797213.95,5753717.71,0]]]}
How do I get query result to app.js and send to webpage (React front end). I'm guessing it needs a callback when data is ready?
You may want to consider using a promise or a callback
Promise approach
db.js
...
module.exports = {
layer: function(layer) {
return new Promise((resolve, reject) => {
connection.query('SELECT ST_AsGeoJSON(geom) FROM nzta_centrelines', (err, result) => {
if (err) {
console.error('Error executing query', err.stack)
return reject(err);
}
var geometry = result.rows[0].st_asgeojson;
console.log(geometry);
return resolve(result);
})
})
}
}
app.js
...
app.post('/layer', async (req, res, next) => {
var layer = req.body.menu;
var geometry = await db.layer(layer);
console.log(geometry);
res.set('Content-Type', 'application/json')
//const body = res.body()
});
Callback approach
db.js
module.exports = {
layer: function(layer, cb) {
connection.query('SELECT ST_AsGeoJSON(geom) FROM nzta_centrelines', (err, result) => {
if (err) {
console.error('Error executing query', err.stack)
return cb(err)
}
var geometry = result.rows[0].st_asgeojson;
console.log(geometry);
return cb(null, geometry);
})
}
}
app.js
...
app.post('/layer', (req, res, next) => {
var layer = req.body.menu;
db.layer(layer, (err, geometry) => {
if (err) throw err;
console.log(geometry);
res.set('Content-Type', 'application/json')
//const body = res.body()
});
});
I would like to fetch all the data (users) from a localdb using mongodb and node.js. but res.json(usersArray) is not displaying anything. I also tried to use .render but it would give me another error.
var express = require('express');
var mongojs = require('mongojs');
var db = mongojs('mongodb://localhost/mydb', ['users']);
var app = express();
const port = 5000;
app.use(express.static(__dirname + "/public"));
app.get('/', function(req, res){
console.log("I received a GET request")
/*
db.users.find(function(err, docs){
console.log("Getting data from db");
console.log(docs);
//res.json(docs);
});
*/
let usersArray = db.users.find().toArray(function(err, docs){
console.log("Getting data from db");
console.log(docs);
//res.json(docs);
});;
res.json(usersArray);
//usersString = JSON.stringify(usersArray);
//res.render(usersString);
//res.json(usersString);
console.log("Returned data");
});
app.listen(port,'0.0.0.0');
console.log('Server running on port '+port);
use async await to block promise-based asynchronous functions
app.get('/', async function(req, res){
console.log("I received a GET request")
let usersArray = await new Promise((resolve, reject) => {
db.users.find().toArray((err, docs) => {
if (err)
reject(err)
resolve(docs)
})
});
res.json(usersArray);
//usersString = JSON.stringify(usersArray);
//res.render(usersString);
//res.json(usersString);
console.log("Returned data");
});
I have some code to create an account and have a login page and say true or false if you entered the correct details but instead it says 'Cannot post /membership/login/submit'.
my main.js code (the html files are basic and the forms are just standard tags with an action and a method, tell me if you want these)
var app = require('express')();
var http = require('http').Server(app);
var httpuse = require('http');
var io = require('socket.io')(http);
var MongoClient = require('mongodb').MongoClient;
var users = require(__dirname + '/local_js/users.js');
var public = __dirname + "/www/";
var bodyParser = require('body-parser')
var url = "mongodb://localhost:27017/";
const bcrypt = require('bcrypt');
var needle = require('needle');
const saltRounds = 10;
app.use(bodyParser.urlencoded({ extended: false }));
function rand(n) {
Math.floor(Math.random() * (n+1));
}
function getToken(hashedpass, user) {
return hashedpass+"_._"+user;
}
app.get('/', function(req, res){
res.sendFile(public + 'index.html');
});
app.get('/membership/create/form', function(req, res){
res.sendFile(public + 'user/create.html');
});
app.post('/membership/create/submit', function(req, res){
MongoClient.connect(url, function(errdd, db) {
if (errdd) throw errdd;
var dbo = db.db("boaichat");
bcrypt.hash(req.body.password, saltRounds, function(err, hash) {
if (err) {throw err;}
var newUser = { nickname: req.body.nickname, password: hash };
dbo.collection("users").insertOne(newUser, function(errd, ress) {
if (errd) throw errd;
console.log("1 user document inserted");
db.close();
res.send("200 OK");
});
});
});
});
app.get('/membership/login/form', function(req, res) {
res.sendFile(public + 'user/login.html');
});
app.post('membership/login/submit', function(req, res) {
MongoClient.connect(url, function(errdd, db) {
if (errdd) throw errdd;
var dbo = db.db("boaichat");
dbo.collection("users").findOne({nickname: req.body.nickname}, function(err, result) {
if (err) throw err;
if (result) {
bcrypt.compare(req.body.password, result.password, function(err, ress) {
console.log(ress);
res.send(ress);
});
}
});
db.close();
});
});
// IGNORE THIS
app.post('api/v1/getSessionValid', function(req, res) {
let token = req.body.token;
let userInfo = token.split('_._');
if (userInfo[0] && userInfo[1]) {
}
});
io.on('connection', function(socket){
console.log('connection');
socket.on('disconnect', function(){
console.log("disconnection");
});
});
http.listen(3000, function(){
console.log('listening on *:3000');
});
it says 'Cannot post /membership/login/submit'.
Don't forget the / at the beginning of your route.
// Try this
app.post('/membership/login/submit', ...)
// Instead of
app.post('membership/login/submit', ...)
TypeError: Cannot read property 'then' of undefined
Can you help me fix this? Thank you.
var express = require('express');
var path = require('path');
var bodyParser = require('body-parser');
var mongodb = require('mongodb');
var dbConn = mongodb.MongoClient.connect('mongodb://localhost:27017',
function(err, db) {
if(err){
throw err;
}else{
console.log("connected");
}
})
var app = express();
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static(path.resolve(__dirname, './')));
app.post('/post-feedback', function (req, res) {
dbConn.then(function(db) {
delete req.body._id; // for safety reasons
db.collection('feedbacks').insertOne(req.body);
});
res.send('Data received:\n' + JSON.stringify(req.body));
});
app.get('/view-feedbacks', function(req, res) {
dbConn.then(function(db) {
db.collection('feedbacks').find({}).toArray().then(function(feedbacks) {
res.status(200).json(feedbacks);
});
});
});
app.listen(process.env.PORT || 3000, process.env.IP || '0.0.0.0' );
TypeError: Cannot read property 'then' of undefined
Can you help me fix this? Thank you.
The following approach should get you started but should not use this for production (Reference: How do I manage MongoDB connections in a Node.js web application?). Read through for another production starters.
var express = require('express');
var path = require('path');
var bodyParser = require('body-parser');
var mongodb = require('mongodb');
var dbConn = function() {
return new Promise((resolve, reject) => {
mongodb.MongoClient.connect('mongodb://localhost:27017',
function(err, db) {
if(err){
return reject(err);
}else{
return resolve(db);
}
});
});
}
var app = express();
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static(path.resolve(__dirname, './')));
app.post('/post-feedback', function (req, res) {
dbConn()
.then(function(db) {
delete req.body._id; // for safety reasons
db.collection('feedbacks').insertOne(req.body);
res.send('Data received:\n' + JSON.stringify(req.body));
})
.catch(err => {
console.log(err)
res.send('Error');
})
});
app.get('/view-feedbacks', function(req, res) {
dbConn()
.then(function(db) {
db.collection('feedbacks').find({}).toArray().then(function(feedbacks) {
res.status(200).json(feedbacks);
});
})
.catch(err => {
console.log(err);
res.status(500).json({});
});
});
app.listen(process.env.PORT || 3000, process.env.IP || '0.0.0.0' );
Production Starter:
Ideally you will have something like following say in a file db.js
let mongoClient = require('mongodb').MongoClient,
logger = require('winston');
function DATABASE() {
this.dbObj = null;
this.myCollection = null; // You will need to add more collections here
}
DATABASE.prototype.init = function (config, options) {
let self = this;
self.config = config; //can pass a config for different things like port, ip etc.
self.logger = logger;
return new Promise(function (resolve, reject) {
if (self.initialized) {
return resolve(self);
}
let connectionUri = "mongodb://localhost:27017"; //self.config.mongo.connectionUri;
mongoClient.connect(connectionUri, {native_parser: true}, function (err, db) {
if (err) {
reject(err);
}
else {
self.dbObj = db;
self.myCollection = db.collection('myCollection');
self.initialized = true;
self.logger.info("db init success");
return resolve(self);
}
});
});
};
var dbObj = null;
var getdbObj = function () {
if (!dbObj) {
dbObj = new DATABASE();
}
return dbObj;
}();
module.exports = getdbObj;
In your main app start file you will have something like:
let dbObj = require('./db.js');
dbObj.init()
.then(db => {
console.log('db initialized successfully');
//db.dbObj.collection('myCollection').find()
//or
//db.myCollection.find() because this has been already initialized in db.js
var app = express();
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static(path.resolve(__dirname, './')));
app.post('/post-feedback', function (req, res) {
delete req.body._id; // for safety reasons
db.dbObj.collection('feedbacks').insertOne(req.body);
res.send('Data received:\n' + JSON.stringify(req.body));
});
app.get('/view-feedbacks', function(req, res) {
//db.collection('feedbacks')
});
app.listen(process.env.PORT || 3000, process.env.IP || '0.0.0.0' )
})
.catch(err => console.log(err));
Try this, dbConn is not promise
app.post('/post-feedback', function (req, res) {
mongoose.connection.db.collection('feedbacks', function (err, collection) {
collection.insertOne(req.body);
res.send('Data received:\n' + JSON.stringify(req.body));
});
// OR
const Model = mongoose.model('feedbacks');
let model = new Model();
model = Object.assign(model, req.body);
model.save().then((result) => {
res.send('Data received:\n' + JSON.stringify(req.body));
});
});
Its working .
If you are getting any TypeError (UnhandledPromiseRejectionWarning: TypeError: db.collection is not a function) form mongodb. Just change the version of mongodb to -
"mongodb": "^2.2.33"
"use strict"
var express = require('express');
var mongodb = require('mongodb');
var app = express();
var MongoClient = mongodb.MongoClient;
var url = 'mongodb://localhost:27017/feedback';
// no need to call then() yet
var dbConn = MongoClient.connect(url);
app.set('port', 5000);
app.listen(app.get('port'), function() {
console.log('feedback is running on port', app.get('port'));
});
app.get('/view-feedback', function(req, res, next) {
// the connection is opened
dbConn.then(function(db) {
// var dbo = db.db("feedback");
db.collection('feedback').find({}).toArray().then(function(docs) {
// return docs;
res.json(docs)
});
});
});
I am trying to get response data from model(database) to controller
here is model
var database = require('../config/db');
exports.getAllBatch = function(done) {
database.query('SELECT batchName from batch', function (err, rows) {
if (err) return console.log(err);
else {
console.log(null, rows);
return rows;
}
})
};
here is controller
code to access data from model.
var express = require('express');
var router = express.Router();
var batch=require('../models/BatchModel');
var myParser = require("body-parser");
var app = express();
router.get('/getbatch', function(req, res, next)
{
var resp=batch.getAllBatch();
res.send(resp);
//not displaying anything on browser
});
});
How I get response on browser please guide me.Thank you in advance.
That is good code, the only thing missing is setting the body parser you have required
app.use(myParser.json())
Your functions are using a callback pattern, but you're not calling or checking the callbacks.
Model
var database = require('../config/db');
exports.getAllBatch = function(done) {
database.query('SELECT batchName from batch', function (err, rows) {
if (err) {
console.log('Err', err);
return done(err);
}
else {
console.log('Rows', rows);
return done(null, rows);
}
});
};
Controller
var express = require('express');
var router = express.Router();
var batch=require('../models/BatchModel');
var myParser = require("body-parser");
var app = express();
router.get('/getbatch', function(req, res, next) {
batch.getAllBatch(function(err, rows) {
if (err) {
res.status(500).send(err);
} else {
res.send(rows);
}
});
});