How to capture response error/message in separate route? - node.js

I just want to capture the response error from a middleware function, it works if I write the code as follows:
var express = require('express');
var expressValidator = require('express-validator');
var app = express();
var bodyParser = require('body-parser');
var router = require('./routes');
//monk.mongoList();
app.use(bodyParser.urlencoded({extented:true}));
app.use(bodyParser.json());
app.use(expressValidator([]));
var port = process.env.PORT || 8978;
router.get('/',function(req,res,next) {
var error = Error('Article is not found');
next(error.message);
return res.send("Hello World!");
});
app.use(function(err,req,res,next) {
console.log(err + "TET");
})
app.listen(port);
but I want to separate the following code:
app.use(function(err,req,res,next) {
console.log(err + "TET");
})
and use it as follows:
app.js
var express = require('express');
var expressValidator = require('express-validator');
var app = express();
var bodyParser = require('body-parser');
var router = require('./routes');
//monk.mongoList();
app.use(bodyParser.urlencoded({extented:true}));
app.use(bodyParser.json());
app.use(expressValidator([]));
var port = process.env.PORT || 8978;
var test = require('./util/test')
app.use(test.logger);
app.use('/',router);
app.listen(port);
console.log('test node API ' + port );
util/test.js
module.exports.logger = function (err, req, res, next) {
console.log('LOGGED')
next()
}
/routes/index.js EDIT: I just edited the /routes/index.js file to make it more simple
var express = require('express');
var router = express.Router();
var url = require('url');
router.get('/api', function(req, res, next) {
var err = "this is error";
var error = Error (err)
var data = { data: "Succuss"}
if (err) {
next(error.message)
res.json({message:err})
}else {
res.json(data);
}
});
module.exports = router;
When add the above code, nothing appear in the console.

Related

Why cannot return params from url nodejs

Here my server code
var express = require("express");
var isAuthen = require('./middleware/authorize')
var router = express.Router();
var app = express();
var order_process = require('./routes/order-process');
app.use('/order',isAuthen, order_process);
and here order_process code
var express = require('express');
var bodyParser = require('body-parser');
const bcrypt = require("bcrypt");
var router = express.Router();
var db = require('../models/database');
router.get('/', urlencodedParser, function (req, res) {
try {
console.log(req.params);
}catch(err){
console.log(err);
}
module.exports = router;
http://localhost:3000/order/2
as i know that url should return number 2 ??
i dont know why it cannot return ?
should return correct params from url
Here's an example of how to get the params from a route:
const express = require('express');
const router = express.Router();
const app = express();
app.use('/order', router);
router.get('/:page', (req, res) => {
res.send(`You are viewing page ${req.params.page}`);
});
const server = app.listen(8000);
Then go to http://localhost:8000/order/2 and you should see it say:
You are viewing page 2

Testing failed with Mocha, Chai and Supertest (NodeJS), retrieving data from mongodb

It is my first time testing the routes in node js and I'm using mocha, supertest and chai. Here is my server.js file:
const express = require('express');
const app = express();
const path = require('path');
const http = require('http').Server(app);
const io = require('socket.io')(http);
const bodyParser = require('body-parser');
const fs = require('fs');
//const helpers = require('./includes/helpers.js');
var cors = require('cors');
app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static(path.join(__dirname, '../dist/chat/')));
require('./listen.js')(http);
app.use((req, res, next) => {
res.setHeader("Access-Control-Allow-Origin","*");
res.setHeader("Access-Control-Allow-Headers","Origin, X-Requested-With, Content-Type, Accept");
res.setHeader("Access-Control-Allow-Methods","GET, POST, PATCH, DELETE, OPTIONS");
next();
});
const MongoClient = require('mongodb').MongoClient;
const url = 'mongodb://localhost:27017';
MongoClient.connect(url, { poolSize: 10 }, function (err, client) {
if (err) { return console.log(err) }
const dbName = 'testdb';
const db = client.db(dbName);
require('./routes/create.js')(app, db);
require('./routes/remove.js')(app, db);
require('./routes/update.js')(app, db);
require('./routes/read.js')(app, db);
require('./routes/add.js')(app, db);
require('./routes/auth.js')(app, db);
require('./routes/search.js')(app, db);
});
And i want to test the read.js route, basically the read route returns a JSON array which has a few key/value parameters e.g. id (key), name (key) etc.
this is my test.js file:
var assert = require('assert');
const express = require('express');
const app = express();
var read = require('../server/routes/read.js');
var http = require('http');
var helpers = require('./include/helpers');
//var api = require('../server/server.js');
var should = require('chai').should();
var expect = require('chai').expect;
var supertest = require('supertest');
var api = supertest('http://localhost:3000');
var request = require('supertest');
describe('The read route',()=>{
it('should be an object with valid parameters',function(done){
api.get('/api/read')
.set('Accept','application/json')
.expect(200)
.end(function(err,res){
if (err) throw err;
expect(res.body).to.not.equal(null);
expect(res.body).to.have.property('id');
done();
});
});
});
The testing works fine, the only issue is that when i run the line: 'expect(res.body).to.have.property('id')' , the test fails saying that expected [], i dont get it whats wrong, my read route returns a JSON array with parameters: {id:4,prodname:'iPhone',type'phone',description:'Nice phone'} (BTW it is returning data from mongodb)
it should detect the id inside the parameter. Any help?

TypeError: Cannot read property 'listOrderJson' of undefined

Im trying to link a route to a controller vs doing the code within the route definiton. Here is my controller:
const {mongoose} = require('../db/mongoose');
const {Order} = require('../models/order');
module.exports.listAllJson = function(req, res) {
res.send({"Here": "something"});
}
And here is my server.js file:
var express = require('express');
var bodyParser = require('body-parser');
var fs = require('fs');
var schedule = require('node-schedule');
var {mongoose} = require('./db/mongoose');
var {Order} = require('./models/order');
var {orderController} = require('./controllers/orderController');
var app = express();
app.use(bodyParser.json());
app.get('/orders', (req, res) => {
orderController.listAllJson().bind(orderController);
});
app.listen(3000, () => {
console.log('Started on port 3000');
});
module.exports = {app};
When I hit my /orders route using postman I get:
TypeError: Cannot read property 'listOrderJson' of undefined error.
I added the 'bind' part to the function call after searching here on stack overflow a ton, but it didn't help. What am I doing wrong here?
orderController is { listAllJson: fn } so you can simply destructure and use it.
var express = require('express');
var bodyParser = require('body-parser');
var fs = require('fs');
var schedule = require('node-schedule');
var {mongoose} = require('./db/mongoose');
var {Order} = require('./models/order');
var {listAllJson} = require('./controllers/orderController');
var app = express();
app.use(bodyParser.json());
app.get('/orders', listAllJson);
app.listen(3000, () => {
console.log('Started on port 3000');
});
module.exports = {app};
Also minor note use res.json({"Here": "something"}); it does the stringifying and set the headers.

breake timer on socket event

I need to break a timer on a socket event and my Nodejs Express Socket.io App looks like this:
app.js
const express = require('express') ;
const app = express();
const server = require('http').Server(app);
const io = require('socket.io')(server);
const api = require('./routes/api');
const users = io.of('/users') ;
const usersNamespace= (socket) => {
socket.on('disconnect',()=>{
});
}
users.on('connection',usersNamespace) ;
app.use('/api', api);
// make socket.io accessible in the express router
app.use((req,res,next)=>{
req.io = io;
req.users = users;
next();
});
server.listen('8000');
my ./routes/api.js file looks like:
var express = require('express');
var router = express.Router();
router.post('/test',req,res) {
// broadcast body of request to users namespace
req.users.emit('restreq',req.body) ;
var timer = setInterval(()=>{
console.log('hello');
}, 5000);
res.status(200).json('received') ;
}
module.exports = router;
The question is how i can do clearInterval and stop the timer on a receiving socket event?
You can pass a function or object to deal with intervals as you do with users:
app.js
const express = require('express') ;
const app = express();
const server = require('http').Server(app);
const io = require('socket.io')(server);
const api = require('./routes/api');
const users = io.of('/drivers') ;
const timer = {
hInterval: null,
register: hInterval => {
timer.hInterval = hInterval
},
disable: () => {
clearInterval(timer.hInterval)
timer.hInterval = null
}
}
const usersNamespace = socket => {
socket.on('disconnect', () => {
timer.disable()
});
}
users.on('connection', usersNamespace) ;
app.use('/api', api);
// make socket.io accessible in the express router
app.use((req, res, next)=>{
req.io = io;
req.users = users;
req.timer = timer;
next();
});
server.listen('8000');
api.js:
var express = require('express');
var router = express.Router();
router.post('/test', req,res) {
// broadcast body of request to users namespace
req.users.emit('restreq',req.body) ;
req.timer.register(setInterval(() => {
console.log('hello');
}, 5000));
res.status(200).json('received') ;
}
module.exports = router;

Node express cannot get static file

This is the picture of my server
https://drive.google.com/file/d/1GA57RyYsc5ik1pSlLhAGtgGjbp_vLFoH/view?usp=sharing
When I go to http://localhost:3000/
I get the error message: Cannot Get/
myserver.js
// TODO: mount the tigers route with a a new router just for tigers
// exactly like lions below
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
var _ = require('lodash');
var morgan = require('morgan');
var lionRouter = require('./lions');
var tigerRouter = require('./tigers');
app.use(morgan('dev'))
app.use(express.static('client'));
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
// this is called mounting. when ever a req comes in for
// '/lion' we want to use this router
app.use('/lions', lionRouter);
app.use(function(err, req, res, next) {
if (err) {
res.status(500).send(error);
}
});
app.listen(3000);
console.log('on port 3000');
Whenever you are trying to visit any url on the browser , then browser makes a GET request to that url, in your case you are not sending any response on the url: "http://localhost:3000/. You can try something like this.
app.route('/*')
.get(function(req, res) {
res.sendFile(path.resolve("./client") + '/index.html'));
});
Check the naming you used, it shows myserver.js instead of server.js as in the picture you uploaded.
Check your routing on line 10 of you code
var lionRouter = require('./lions');
var tigerRouter = require('./tigers');
. try this edited codes
server.js
// TODO: mount the tigers route with a a new router just for tigers
// exactly like lions below
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
var _ = require('lodash');
var morgan = require('morgan');
var lionRouter = require('./server/lions');
var tigerRouter = require('./server/tigers');
app.use(morgan('dev'))
app.use(express.static('client'));
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
// this is called mounting. when ever a req comes in for
// '/lion' we want to use this router
app.use('/lions', lionRouter);
app.use(function(err, req, res, next) {
if (err) {
res.status(500).send(error);
}
});
app.listen(3000);
console.log('on port 3000');
Express static directory is given client but it is present on parent directory.
So i have resolve this issue with path module and now this will work for you.
// TODO: mount the tigers route with a a new router just for tigers
// exactly like lions below
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
var _ = require('lodash');
var morgan = require('morgan');
var path = require('path')
var lionRouter = require('./lions');
var tigerRouter = require('./tigers');
app.use(morgan('dev'))
app.use(express.static(path.join(__dirname, '../client')));
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
// this is called mounting. when ever a req comes in for
// '/lion' we want to use this router
app.use('/lions', lionRouter);
app.use(function(err, req, res, next) {
if (err) {
res.status(500).send(error);
}
});
app.listen(3000);
console.log('on port 3000');
Your code works fine after commenting the following three lines of your code:
var lionRouter = require('./lions');
var tigerRouter = require('./tigers');
app.use('/lions', lionRouter);
Check if any error is present in LionsJS.

Resources