I have declared socket.io in index.js file, And I would pass soket object to route module.
const express = require('express');
const app = express();
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
var MongoClient = require('mongodb').MongoClient;
var server = require('http').Server(app);
var io = require('socket.io')(server);
var routes = require('./routes/routes')(io);
const dbb = mongoose.connect("mongodb://xxx:xxx#ds137600.mlab.com:37600/tasksdb");
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
app.use('/', routes);
var server= app.listen(3000, function () {
console.log('Example app listening on port 3000!')
})
routes.js
var express = require("express"); // call express
var taskSchema = require("../models/taskModel");
var mongoose = require("mongoose");
var router = express.Router(); // get an instance of the express Router
router
.route("/tasks")
.post(function (req, res, next) {
....
});
router
.route("/tasks")
.get(function (req, res) {
....
});
module.exports = router;
How can I transfert it to routes.js? what are the different ways to do it ? I still not well understanding how modules works
For server:
const app = express();
app.use(logger('tiny'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
app.use((req, res, next) => {
const origin = req.headers.origin;
if (allowed_header.indexOf(origin) > -1) {
res.header('Access-Control-Allow-Origin', origin);
}
res.header(
'Access-Control-Allow-Headers',
'Origin, X-Requested-With, Content-Type, gutsyJwt, Accept'
);
next();
});
app.io = require('socket.io')({
origins: ['*:*'],
});
require('./routes')(app);
module.exports = app;
Then in route:
module.exports = app => {
app.post('/api/bar', (req, res) =>
fooController.bar(req, res, app.io)
);
};
Then in controller:
module.exports = {
bar(req, res, io) {
io.emit('message', req.body.message);
res.status(200).send({msg: 'Message broadcasted!'});
},
};
In this post, it is asking the similar question as well if you need more reference.
ExpressJS how do I pass objects with state (eg. connections)?
Related
I'm using express-subdomain.
The router that handles requests through a subdomain is the same as the router that handles requests without a subdomain.
I know that my 'app.js' setting is wrong.
How can I solve this problem? I want to know a good way. like this:
app.use(subdomain('banana', ('/about', bananaRouter);
and If this is an easy question, please forgive me. I couldn't find any of the same problems in my country. I'm sorry.
// /app.js
const appleRouter = require('./routes/apple/index');
const appleAboutRouter = require('./routes/apple/about');
const applePriceRouter = require('./routes/apple/price');
const bananaRouter = require('./routes/banana/index');
const bananaAboutRouter = require('./routes/banana/about');
const bananaPriceRouter = require('./routes/banana/price');
const grapeRouter = require('./routes/grape/index');
const grapeAboutRouter = require('./routes/grape/about');
const grapePriceRouter = require('./routes/grape/price');
app.use(subdomain('banana', bananaRouter));
app.use(subdomain('grape', grapeRouter));
app.use('/', appleRouter);
app.use('/about', appleAboutRouter);
app.use('/price', applePriceRouter);
app.use('/', bananaRouter);
app.use('/about', bananaAboutRouter);
app.use('/price', bananaPriceRouter);
app.use('/', grapeRouter);
app.use('/about', grapeAboutRouter);
app.use('/price', grapePriceRouter);
// /routes/apple/index
const express = require('express');
const router = express.Router();
router.get('/', function (req, res, next) {
res.send('I am Apple');
});
module.exports = router;
// /routes/apple/about
const express = require('express');
const router = express.Router();
router.get('/view', function (req, res, next) {
res.send("Apples don't taste good.");
});
module.exports = router;
// /routes/apple/price
const express = require('express');
const router = express.Router();
router.get('/view', function (req, res, next) {
res.send("$ 1");
});
module.exports = router;
// /routes/banana/index
const express = require('express');
const router = express.Router();
router.get('/', function (req, res, next) {
res.send('I am Banana');
});
module.exports = router;
// /routes/banana/about
const express = require('express');
const router = express.Router();
router.get('/view', function (req, res, next) {
res.send("Bananas are delicious.");
});
module.exports = router;
// /routes/banana/price
const express = require('express');
const router = express.Router();
router.get('/view', function (req, res, next) {
res.send("$ 2");
});
module.exports = router;
// /routes/grape/index
const express = require('express');
const router = express.Router();
router.get('/', function (req, res, next) {
res.send('I am Grape');
});
module.exports = router;
// /routes/grape/about
const express = require('express');
const router = express.Router();
router.get('/view', function (req, res, next) {
res.send("Grapes are purple.");
});
module.exports = router;
// /routes/grape/price
const express = require('express');
const router = express.Router();
router.get('/view', function (req, res, next) {
res.send("$ 3");
});
module.exports = router;
Expected Behaviour 2:
// http://localhost.com:3000/
I am Apple
// http://localhost.com:3000/about/view
Apples don't taste good.
// http://localhost.com:3000/price/view
$ 1
// http://banana.localhost.com:3000/
I am Banana
// http://banana.localhost.com:3000/about/view
Apples don't taste good. ** not Bananas are delicious. **
// http://banana.localhost.com:3000/price/view
'$ 1' ** not '$ 2' **
I created code sample which resolve you problem :D Firstly you need to add a couple lines to your /etc/hosts file. Example
127.0.0.1 banana.myapp.dev
127.0.0.1 myapp.dev
And after that try to run this script which I wrote for you:
//connect express
var express = require('express');
var subdomain = require('express-subdomain');
var app = express();
app.use(express.json());
//set sub routing
app.sub_banana = express.Router();
app.use(subdomain('banana', app.sub_banana));
//top level routing
app.get('/', (req, res) => {
res.send('I am Apple')
});
app.get('/about', (req, res) => {
res.send('Apples don\'t taste good.')
});
//subdomain routing
app.sub_banana.get('/', (req, res) => {
res.send('I am Banana')
});
app.sub_banana.get('/about', (req, res) => {
res.send('Apples don\'t taste good. ** not Bananas are delicious. **')
});
//start server
var http = require('http');
var port = 3000
app.set('port', port);
var server = http.createServer(app);
server.listen(port);
Let me know if you need more information. I got my answer from this resource https://exceed-team.com/tech/express-subdomain
I am trying to build a webchat app using node.js and express. I have a router file and a server file, together with some client files. I would like to emit a join event from the router and processing it on the server so the user can join the room. I did i like this
Server.js
const express = require('express');
const layout = require('express-layout');
const app = express();
var server = require('http').createServer(app);
var io=require('socket.io')(server);
const routes = require('./router')(io);
const bodyParser = require('body-parser');
var fs = require("fs");
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
const middleware = [
layout(),
express.static(path.join(__dirname, 'public')),
bodyParser.urlencoded(),
];
app.use(middleware);
app.use('/', routes);
app.use((req, res, next) => {
res.status(404).send("Sorry can't find that!");
});
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).send('Something broke!');
});
io.on('connect', onConnect);
function onConnect(socket) {
var contents = fs.readFileSync("./public/rooms.json");
let rooms = JSON.parse(contents);
socket.emit('parse',rooms);
socket.on('join',function (name, room) {
console.log(name+" "+ room);
socket.join(room);
socket.user=name;
socket.room=room;
})
}
Here I just initialize the io connection together with all the dependencies I use. I use const routes = require('./router')(io); to pass the io variable
router.js
const express = require('express');
const User= require("./public/classes/User");
const router = express.Router();
const {check, validationResult} = require('express-validator');
const {matchedData} = require('express-validator/filter');
var userlist=new Array();
router.get('/', (req, res) => {
res.render('index', {
data: {},
errors: {}
})
});
router.post('/enter', [
check('username')
.isLength({min: 1})
.withMessage('Username is required').trim() //implement personalized check
], (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.render('index', {
data: req.body,
errors: errors.mapped()
})
}
const data = matchedData(req)
handleJoin(data);
});
return router;
//MOVE TO SUPPORT
function find(name) {
return 1;
}
function handleJoin (data){
if(find(data.username)){
const newUser= new User (data.username, data.room,"");
userlist.push(newUser);
io.emit('join',newUser.name,newUser.room);
}
};
};
The console should log the name and the choosen room but it doesn't. How do I process this?
I'm trying to load /users/(username) for specific user profile pages, however I'm getting a Cannot GET /users/test error. I had it working at one point but then I added a function and it's broken again (I'm thinking the problem may be there in the route). Here's the relevant files. Any help would be greatly appreciated. Thank you!
app.js:
const fs = require('fs');
const _ = require('lodash');
const express = require('express');
const path = require('path');
const cookieParser = require('cookie-parser');
const bodyParser = require('body-parser');
const exphbs = require('express-handlebars');
const expressValidator = require('express-validator');
const flash = require('connect-flash');
const session = require('express-session');
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
const mongo = require('mongodb');
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/tipcup');
var db = mongoose.connection;
const routes = require('./routes/index');
const users = require('./routes/users');
const user = require('./routes/user');
// Init App
var app = express();
// View Engine
app.set('views', path.join(__dirname, 'views'));
app.engine('handlebars', exphbs({defaultLayout: 'layout'}));
app.set('view engine', 'handlebars');
// BodyParser middleware
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false}));
app.use(cookieParser());
// Set Static Folder
app.use(express.static(path.join(__dirname, 'public')));
// Express Session
app.use(session({
secret: 'secret',
saveUninitialized: true,
resave: true
}));
// Passport Init
app.use(passport.initialize());
app.use(passport.session());
// Express Validator
app.use(expressValidator ({
errorFormatter: function(param, msg, value) {
var namespace = param.split('.')
, root = namespace.shift()
, formParam = root;
while(namespace.length){
formParam += '[' + namespace.shift() + ']';
}
return {
param: formParam,
msg: msg,
value: value
};
}
}));
// Connect Flash
app.use(flash());
// Global Vars
app.use(function (req, res, next){
res.locals.success_msg = req.flash('success_msg');
res.locals.error_msg = req.flash('error_msg');
res.locals.error = req.flash('error');
res.locals.user = req.user || null;
next();
});
app.use('/', routes);
app.use('/users', users);
app.use('/user/:username', user);
// Set Port
app.set('port', (process.env.PORT || 3000));
app.listen(app.get('port'), function(){
console.log('Server started on port '+app.get('port'));
});
user.js route:
var express = require('express');
var router = express.Router();
var User = require('../models/user');
// GET user by username
router.get('/:username', function(req, res) {
//var username = req.params.username;
User.getUserByUsername(function(err, user) {
if(err) {
res.send('error');
next();
}
const vm = user;
res.render('user', vm);
});
//res.render('user');
});
module.exports = router;
Its looks like you are defining the User Id twice
In app.js you are mounting the users routes /user/:username with the line
app.use('/user/:username', user);
Then in user.js you are declaring the get to /:username with the line
router.get('/:username', function(req, res) {
I would think this would produce a route with the signature /user/:username/:username
I would suggest remove the /:username one of the files
router.get('/:username', function(req, res) {
var username = req.params.username;
User.getUserByUsername(username).then(function(err, user){
res.json(user);
});
for mongoose you can do this:
router.get('/:username', function(req, res) {
var username = req.params.username;
User.getUserByUsername(username,function(err, user){
res.json(user);
});
});
When I try to import my routes module into the main app with app.use(require(./routes)) I get app.use() requires middleware functions. How should I go about the module.exports function to make it work?
My routes:
var express = require('express'),
auth = require('../middleware/auth.js'),
user = require('../models/user.js'),
formidable = require('formidable');
module.exports = (function () {
app.post('/', function (req, res) {
var form = new formidable.IncomingForm();
form.parse(req, function (err, fields, files) {
user.create(fields.username, fields.email, fields.password);
});
res.render('./game/game.html', {});
});
app.get('/', function (req, res) {
res.render('./index.html', {});
});
app.get('/game', function (req, res) {
res.render('/views/index.html');
});
})();
My main app.js:
var express = require('express'),
app = require('express')(),
cookieSession = require('cookie-session'),
ejs = require('ejs'),
path = require('path'),
cookieParser = require('cookie-parser'),
util = require('util'),
port = process.env.PORT || 3000,
auth = require('./middleware/auth.js'),
user = require('./models/user.js'),
formidable = require('formidable');
router = express.Router();
app.use(express.static(path.join(__dirname, 'public')));
app.set('views', __dirname + '/views');
app.engine('html', require('ejs').renderFile);
app.set('view engine', 'html');
//won't import routes
app.use(require('./routes'));
module.exports = router;
app.listen(port);
You need to return app in your exports function
module.exports = function (express) {
var app = express.Router();
app.post('/', function (req, res) {
var form = new formidable.IncomingForm();
form.parse(req, function (err, fields, files) {
user.create(fields.username, fields.email, fields.password);
});
res.render('./game/game.html', {});
});
app.get('/', function (req, res) {
res.render('./index.html', {});
});
app.get('/game', function (req, res) {
res.render('/views/index.html');
});
return app
};
......
app.use(require('./routes')(express));
Your routes need to be an instance of Express Router.
var express = require('express');
var router = express.Router();
router.get('/', function(req, res, next) {
res.send(req.headers);
});
module.exports = router;
Now in your app.js you can use them as following:
app.use('/', require('./routes/index'));
Your module should either mutate your router (app), or create its own router and export it.
Solution 1
Module
module.exports = function(app) {
app.post(...);
app.get(...);
}
Main app
require("./routes")(app)
Solution 2
Module
var app = express.Router();
app.post(...);
app.get(...);
module.exports = app;
Main app
app.use(require("./routes"))
Solution 2 is better in my opinion because it avoids mutation.
I am learning node and express to create an api for an angular app I will be creating.
When I try and post something the req.body seems to be blank.
This is my server.js file
'use strict';
var express = require('express'),
app = express(),
mongoose = require('mongoose'),
router = require('./api'),
bodyParser = require('body-parser');
mongoose.connect('mongodb://localhost/my_db');
app.use(bodyParser.json());
app.use('/api', router);
app.get('/', function(req, res) {
res.render(__dirname + '/index.jade');
});
app.listen(3001, function() {
console.log('Listening on port 3001');
});
and this is my api/index.js file:
'use strict';
var express = require('express'),
Todo = require('../models/todo'),
router = express.Router();
router.get('/todos', function(req, res) {
Todo.find({}, function(err, todos) {
if(err) {
return console.log(err);
}
res.json({todos: todos});
});
});
router.post('/todos', function(req, res) {
var todo = req.body;
res.json({todo: todo});
});
module.exports = router;
when I use postman to post this to http://localhost:3001/api/todos:
{
'name': 'Walk the Dog',
'completed': false
}
my response is:
{
"todo": {}
}
I can't see why this would be blank, any help is appreciated.
UPDATE
Turns out I was posting text in postman instead of JSON.
use this in your server.js file
app.use(bodyParser.urlencoded({extended:true}));
app.use(bodyParser.json());