How to pass json object from controller to router? - javascript

I have a data in controller from mongodb now i want to send this json object to router so i can send to client side using api , with below code i am getting an error TypeError: Cannot read property 'json' of undefined Any idea what is implemented wrong ?
controller.js
var Diagram = require('./diagram.model');
var mongoose = require('mongoose');
module.exports = function index(req,res) {
Diagram.find({}, function(err, result) {
if (!err) {
console.log('Response from controller', result);
return res.json(result);
}
});
}
router.js
var express = require('express');
var controller = require('./diagram.controller');
var router = express.Router();
console.log('THis is in router',controller.index);
router.get('/getAllDiagram',controller.index);
module.exports = router;

I think the module.exports (see my comment above) is the problem. What do you think about writing your request handling straightforward first (so that you have a feeling of success (: ):
const express = require('express');
const app = express();
app.get('/getAllDiagram', (req, res) => {
Diagram.find({}, function(err, result) {
if (err) {
console.error(`Error in finding diagram: ${err.message}`);
return res.status(500);
}
res.json(result);
});
});
app.listen(8080);
Advanced version
controller.js
const Diagram = require('./diagram.model');
module.exports.index = (req, res) => {
Diagram.find({}, function(err, result) {
if (err) {
console.error(`Error in finding diagram: ${err.message}`);
return res.status(500);
}
res.json(result);
});
};
router.js
const express = require('express');
const controller = require('./controller');
const router = express.Router();
router.get('/getAllDiagram', controller.index);
module.exports = router;
app.js
const express = require('express');
const router = require('./router');
const app = express();
app.use(router);
app.listen(8080);
Important: Please check the module.exports.index declaration. That was wrong in your code snippet.

Related

Returning remote API data within Express app

I have an express app where I just return data from another remote API. Below is the file snippet. I cannot use normal node-fetch or request as my remote API uses NTLM auth.
const express = require('express');
const router = express.Router();
const httpntlm = require('httpntlm');
const url = 'http://myremoteapi.com/products';
router.get('/', function(req, res, next) {
httpntlm.get(
{
url,
username: 'my_user',
password: 'my_pass
},
(err, resp) => {
if (err) return err;
res.send(JSON.parse(resp.body));
}
);
});
module.exports = router;
Everything works fine.
Now, I'd like to take the remote API call outside the router method in a function called getData.
const express = require('express');
const router = express.Router();
const httpntlm = require('httpntlm');
const url = 'http://myremoteapi.com/products';
const getData = httpntlm.get(
{
url,
username: 'my_user',
password: 'my_pass
},
(err, resp) => {
if (err) return err;
return JSON.parse(resp.body);
}
);
router.get('/', function(req, res, next) {
res.send(getData) // returns undefined
});
module.exports = router;
I am unable to get the same result. Also, I found that the httpntlm method does not return a Promise which I can resolve.
One way to solve this is to create the Promise yourself:
const express = require('express');
const router = express.Router();
const httpntlm = require('httpntlm');
const url = 'http://myremoteapi.com/products';
const getData = () => new Promise((resolve, reject) => {
httpntlm.get({
url,
username: 'my_user',
password: 'my_pass'
},
(err, resp) => {
if (err) reject(err);
else resolve(JSON.parse(resp.body));
}
);
});
router.get('/', function(req, res, next) {
getData().then(data => res.send(data));
});
module.exports = router;
By wrapping httpntlm.get like that it becomes thenable, and by making getData a function the data is fetched anew whenever you call it.

Node.js restful webservice using express and mongoose. Routing not working

I'm trying to build a RESTful webservice following this tutorial:
https://www.codementor.io/olatundegaruba/nodejs-restful-apis-in-10-minutes-q0sgsfhbd
It's not working returning me a CANNOT GET/ reports error...
I'm trying to learn node.js and I can't find the error anywhere and everything I tried didn't work.
Also, when I call the server, it reaches to index.js which prints a "HEY". Wasn't this supposed to reach server.js first?
Here is my code:
Server.js
var express = require('express'),
app = express(),
port = process.env.PORT || 3000,
mongoose = require('mongoose'),
Report = require('./api/models/reportModel.js'),
bodyParser = require('body-parser');
mongoose.Promise = global.Promise;
mongoose.connect('mongodb://localhost/server');
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
var routes = require('./api/routes/reportRoute.js');
routes(app);
app.listen(port);
console.log('Report RESTful API server started on: ' + port);
reportRoute.js
'use strict';
module.exports = function(app) {
var reports = require('../controllers/reportController.js');
// report Routes
app.route('/reports')
.get(reports.list_all_reports)
.post(reports.create_a_report);
app.route('/reports/:reportId').get(reports.read_a_report)
.put(reports.update_a_report)
.delete(reports.delete_a_report);
};
reportController.js
'use strict';
var mongoose = require('mongoose'),
Report = mongoose.model('Reports');
exports.list_all_reports = function(req, res) {
Report.find({}, function(err, report) {
if (err)
res.send(err);
res.json(report);
});
};
exports.create_a_report = function(req, res) {
var new_report = new Report(req.body);
new_report.save(function(err, report) {
if (err)
res.send(err);
res.json(report);
});
};
exports.read_a_report = function(req, res) {
Report.findById(req.params.reportId, function(err, report) {
if (err)
res.send(err);
res.json(report);
});
};
exports.update_a_report = function(req, report) {
Report.findOneAndUpdate({_id: req.params.taskId}, req.body, { new: true }, function(err, report) {
if (err)
res.send(err);
res.json(report);
});
};
exports.delete_a_report = function(req, res) {
Report.remove({
_id: req.params.reportId
}, function(err, report) {
if (err)
res.send(err);
res.json({ message: 'Report successfully deleted' });
});
};
Thank you for your help...
EDIT:
index.js
const express = require('express');
const app = express();
var route = require('./api/routes/reportRoute');
app.get('/', function(req, res) {
res.send('HEY!');
})
app.listen(3000, function(){console.log('Server running on port 3000')});
You haven't posted your reportController.js but this problem will occur if the function list_all_reports does not set a response body. For example, adding
res.json({hello: "world"});
to the handler function should make it work.

Could somebody explain how to pass globally the database variable in express.js?

already tried a lot of tutorials, but somehow I could not figure it out.
I am using mongodb and express.js
this is in my server.js
const express = require('express');
const subdomain = require('express-subdomain');
const bodyParser= require('body-parser');
const MongoClient = require('mongodb').MongoClient;
const routes = require('./routes');
const app = express();
var db;
app.set('view engine', 'pug');
app.use(bodyParser.urlencoded({extended: true}));
app.use(express.static('views'));
app.use(subdomain('api', routes.api));
MongoClient.connect('mongodb://localhost:27017/test', (err, database) => {
if (err) return console.log(err);
db = database;
app.listen(3000, () => {
console.log('listening on 3000');
});
});
and this is in my routes.js
const express = require('express');
const api = express.Router();
api.get('/', function (req, res) {
db.collection('test').find().toArray((err, result) => {
if (err) return console.log(err);
res.render('api_orders', {test: result});
});
});
module.exports = {
api
}
I would like to use the db variable also in routes, but it always gives me the db is not defined error (obviously) I read that I should somehow export the db var, but could not managed to do it
Instead i would suggest you to create another file and you just require it where you want to use it. Suppose:
db.js:
const MongoClient = require('mongodb').MongoClient;
const db = function(){
return MongoClient.connect('mongodb://localhost:27017/test', (err, database) => {
if (err) return console.log(err);
return database;
});
}
module.exports = db;
Now you can use the db anywhere when you do :
const mydb = require('./db'); // <--require it to use
It may not work as it is not tested but it can give you idea to get through.
This is as much a question as a response. I've used
MongoClient.connect('mongodb://localhost:27017/test', (err, database)={
global.bigdb = database
});
and called it from the routes for instance
var col = global.bigdb.collection('collectionname');
Is this bad practice? Rereading the code - it's been live for a while - I'm also exposing the redis client as a global.
Any info appreciated. Live with no bug reports but very curious if I should refactor.
app.use(function(req,res,next))
{
res.locals.yourvariable = null;
next();
});
This is how I initialize global variables. Hope you get an idea.

Express routes returning 404s

I have a couple of simple routes that I have misconfigured and not sure why.
app.js:
//app setup
var http = require('http');
var bodyParser = require('body-parser');
var express = require('express');
var routes = require('./routes');
var agent = require('./routes/agent');
var config = require('./config');
var app = express();
app.server = http.createServer(app);
app.use(bodyParser.json({
limit : config.bodyLimit
}));
app.use(bodyParser.urlencoded({
extended : true
}));
app.use('/v1', routes);
app.use('/v1/agent', agent);
app.server.listen(config.port);
console.log('API listening on port ' + app.server.address().port);
module.exports = app;
This returns responses on the /v1/ route (index.js):
'use strict';
var express = require('express');
var router = express.Router();
router.get('/', function (req, res) {
res.status(403).json({
message: 'Invalid request.'
});
});
module.exports = router;
in the agent route, I have a POST handler that is being handled correctly at /v1/agent/login. But while a GET routed at /v1/agent/ works, a GET routed to /v1/agent/123 returns a 404:
'use strict';
var agentController = require('../controller/agent.js');
var express = require('express');
var router = express.Router();
function handleError(objError, res) {
res.status(500).json({ errorMessage : objError.message });
}
router.get('/', function (req, res) {
res.status(200).json({
message: 'OK' // works fine
});
});
router.get('/:id'), function (req, res) {
var agentNum = req.params.id;
res.send(req.params); // 404 here
try {
//res.status(200).json({ message: 'hello agent.'});
} catch (err) {
// handleError(err, res);
}
};
router.post('/login', function (req, res) {
var agentNum, password;
// works fine
});
router.post('/pwr', function (req, res) {
//also works fine
});
module.exports = router;
My understanding is that the app.use method should redirect the route and any GET requests appended to that route to the one I specified (agent), so why is it that the one with params fails while the root one succeeds?
Thank you
You're not passing the callback correctly.
router.get('/:id')
router.get('/:id', function(req, res) {
var agentNum = req.params.id;
res.send(req.params); // 404 here
try {
//res.status(200).json({ message: 'hello agent.'});
} catch (err) {
// handleError(err, res);
}
});

MongoDB - TypeError: users.aggregate is not a function

I'm trying to query a collection using aggregate but getting TypeError: users.aggregate is not a function. Here's my code:
./app.js (reduced to fit)
var express = require('express');
var mongo = require('mongodb');
var monk = require('monk');
var db = monk('localhost:27017/mydb');
var users = require('./routes/users');
var app = express();
app.use(function(req, res, next) {
req.db = db;
next();
});
app.use('/users', users);
module.exports = app;
./routes/users.js
var express = require('express');
var router = express.Router();
router.get('/test', function(req, res) {
var users = req.db.get('users');
users.aggregate([{ $match: { username: 'test0' }}], function(err, data) {
res.json(data);
});
});
module.exports = router;
I'm running MongoDB version 3.2.10 and the above query works fine in the console. I've looked up solutions and they all suggest to check the MongoDB version, which I've already done. I've also tried req.db.collection('users').aggregate (as suggested by another post) and receive a similar error: req.db.collection is not a function. What am I missing?
EDIT:
Running users.find({ username: 'test0' }, func... works and returns correct data.
EDIT2: Added more code.
You can do like this.
var app = require('express')();
var expressMongoDb = require('express-mongo-db');
app.use(expressMongoDb('mongodb://localhost/test'));
app.get('/', function (req, res, next) {
req.db // => Db object
});
I tried with this. It is working in my local.
var app = require('express')();
const db = require('monk')('localhost/test')
app.use(function(req,res,next){
req.db = db;
next();
});
app.get('/', function (req, res, next) {
var db = req.db;
var users = db.get('users');
users.aggregate([
{$match: { firstName: 'Test 2' }}
]).then(function(docs) {
console.log(docs)
})
});
app.listen(3010, function () {
console.log('Example app listening on port 3010!');
});

Categories

Resources