So, its been a hot minute since I've used node, and i can not for the life of me, understand why this isn't working.
const body_parser = require("body-parser");
var express = require("express");
var app = express();
app.use("/", express.static(__dirname + "/Contents/"));
app.get("/", function(req, res) {
//Why wont this log to my terminal when a user visits the site?
console.log("log it pleaseeeeeeeeee");
});
app.listen(5004, () => {
console.log("server up and listening on port 5004");
});
I'm trying to log "Log it Pleaseeeee" every time a user visits the site, into the terminal where my nodejs app is running. Why wont this work?
You can't have 2 seperate handlers for an endpoint, in your case "/"
To achieve what you want, you must provide a middleware function.
express will know based on the type of the second argument what to do. middleware functions expect 3 arguments; the last being a callback so it knows when you are ready.
You should change your code by moving your get function into your app.use('/', ...) function and including the callback parameter as follows:
const body_parser = require("body-parser");
var express = require("express");
var app = express();
app.use("/", function(req, res, callback) {
console.log("log it pleaseeeeeeeeee");
callback()
}, express.static(__dirname + "/Contents/"));
/** GET RID OF THIS
app.get("/", function(req, res) {
//Why wont this log to my terminal when a user visits the site?
console.log("log it pleaseeeeeeeeee");
});
*/
app.listen(5004, () => {
console.log("server up and listening on port 5004");
});
Related
I am using the express framework for a node.js backend server. I am using the express router to define the different routes.
This is my app.js file:
var express = require('express');
var app = express();
var server = require('http').Server(app);
var cors = require('cors');
app.use(cors());
app.use(express.json());
var route = require('./route');
app.use('/api/', route);
server.listen(3000, () => {
console.log('App running on port 3000!');
});
This is my router route.js:
var express = require('express');
var router = express.Router();
var controller = require('./controller');
router.use(function (req, res, next) {
next();
router.get('/test', function (req, res, next) {
controller.get(req, res, next);
});
});
module.exports = router;
The route itself uses a controller for the logic controller.js
exports.get = function (req, res, next) {
res.send('Hello World');
}
Starting the app with node app.js and calling the defined route http://localhost:3000/api/test will result in a Cannot GET /api/test on the first try. Calling the route a second time however will result in the expected answer hello world.
What is the reason for the first call failing? Why does it work on the second try? Any ideas are appreciated
Because router.use(function (req, res, next) { will only get executed on the first request, and when you call next() the route was not yet added. Afterwards you call router.get(...) which will add the route, so it will be available the next time.
Nevertheless thats just bad, move the .get(...) outside of .use(...) (you can also get rid of it entirely).
I'm using Express4 with a router that points to path /, and that is handled by a JS file named chat.js.
And my IO object is already bind to app.io, so inside my chat.js I'll call my Socket.IO by using req.app.io, but the problem is, I use to be using socket.emit and the code just work fine, but now if I want to sync up with the client I have to using req.app.io.emit.
And since because I'm using req.app.io.emit, I have the connection keep increasing problem.
index.js
const express = require('express');
const app = express();
const http = require('http');
const server = http.createServer(app);
const path = require('path');
const randomstring = require('randomstring');
const sha256 = require('sha256');
const io = require('socket.io').listen(server);
app.io = io;
const port = process.env.PORT || 3000;
module.exports.users = {};
server.listen(port, () => {
console.log(`Serer is running on port ${port}`);
});
app.set('view engine', 'ejs');
app.set('views', path.join(`${__dirname}/../public`));
app.use('/static', express.static(path.join(`${__dirname}/../public`)));
app.use('/', require('./chat'));
chat.js
const express = require('express');
const router = express.Router();
const users = require('./index').users;
const randomstring = require('randomstring');
router.get('/', (req, res) => {
res.render('index');
const uid = randomstring.generate(30);
users[uid] = true;
req.app.io.on('connection', socket => {
console.log('hello');
socket.on('disconnect', () => {
console.log('bye');
});
});
});
module.exports = router;
Log(Image)
Serer is running on port 3000
hello
bye
hello
hello
bye
bye
Every time your / route is hit, you create a new duplicate io.on('connection', ...) event handler. So, after that route is hit 3 times, you have 3 event handlers for the connection event. So, when it occurs, your code gets called 3 times.
Instead, you should do the io.on('connection', ...) only once outside the route.
FYI, you don't seem to be doing anything useful with the uid you are creating because you don't associate it with any particular connection. FYI, each socket.io connection already has a unique socket.id which is uniquely associated with each socket.io connection so that you can get the id from the socket or can retrieve the socket given only the id.
I am using node + redis and I facing strange issue when ever I run my app , connect event of redis client is called multiple times automatically as written in redis.js file.
Below is my code Server.js:
var express=require('express');
var app=express();
var port=8000;
var path = require('path');
var logger=require('morgan');
var bodyParser = require('body-parser');
var router = express.Router();
app.use(logger('dev'));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.get('/',function(req,res){
res.send({message:"Welcome to nodejs APIS"});
});
var redisObj=require('./redis.js');
app.use('/redischeck',redisObj);
app.listen(port,function(err,res){ if(err){ console.log("Server error");}else{console.log("Server running on port 8000");}});
redis.js
var express = require('express');
var router = express.Router();
var redis = require("redis");
var client = redis.createClient();
client.on('connect', function() {
console.log('connected'); // Prints multiple time in console
});
router.get('/', function(req, res) {
client.on("error", function (err) { console.log("Error " + err);});
client.set("foo", "bar", function (err, reply) {
client.quit();
res.json({status:'Success'});
});
});
module.exports=router;
I also cross checked this issue using 'netstat -na | grep 6379'.My observation were many connection were created and then went in to TIME_WAIT state which was strange because I just ran my app on my localhost without anyone connecting it from some other end.
Am I doing something wrong in code.
It was a mistake from my side I had changed timeout values in redis.conf file located at /etc/redis/redis.conf so that redis connection does not go in TIME_WAIT state for 60 sec.
I'm trying to modularize my application files and I'm having problems with Socket.io. I would like to use the io inside my routes.js. Something like this:
var router = require('express').Router();
var io = require('./sockets/my-io');
router.get('/', function(req, res) {
io.emit('request-detected');
});
module.exports = router;
But I can't do, because the socket.io needs the app server, and when I'm inside the routes.js file, the app server is not listening or being exported yet.
Can you give me a solution, or any other approach to this problem?
Here's what I have, and if it's possible, I would like to keep the file structure:
app.js
var app = require('express')();
var routes = require('./routes');
/* ... */
app.use('/contacts', routes);
module.exports = app;
bin/www
#!/usr/bin/env node
var app = require('../wallet');
var server = app.listen(port, function() {
debug('Express is listening o port ' + port);
});
routes.js
var router = require('express').Router();
router.get('/', function(req, res) {
console.log('hey');
});
module.exports = router;
You can do it by passing the io variable to your routes module.
bin/www
#!/usr/bin/env node
var app = require('./app');
var server = app.listen(3000, function() {
console.log('Express is listening on port 3000');
}); // start the server
var socket = require('./socket')(server); // require socket.io code
var routes = require('./routes')(socket); // require routes
app.use('/', routes);
app.js
var express = require('express');
var app = express();
app.use(express.static(__dirname + '/public'));
app.set('views engine', 'ejs');
app.set('views', __dirname + '/');
module.exports = app;
socket.js
var socketio = require('socket.io');
function init(server) {
var io = socketio(server);
io.on('connection', function (socket) {
console.log("socket connected");
socket.on('newEvent', function (data) {
console.log(data);
});
});
return io;
}
module.exports = init;
routes.js
var express = require('express');
var route = express.Router();
function init(io) {
route.get('/', function (req, res) {
res.render('index.ejs', {});
setTimeout(function() {io.emit('newEvent', {message: "Hi from the server"})}, 2000);
});
return route;
}
module.exports = init;
The code above worked for me. However, I'm not sure why you want to do that.
Inside the router, you still have full control of what you want to send to the user via html, so you can just add the data to the html directly.
The idea of socket.io is that you can send data between the client and back once he has loaded the html and established a connection to your server with socket.io.
As you can see in the routes.js, I had to add a timeout to the emit. This is because the socket event will be emit before the browser has reloaded the page. In my case the browser logged the event and then immediately refreshed, losing the data you just sent.
Another problem is that you don't know anything about the socket of the client that is requesting the page because he hasn't connected yet. This means that calling io.emit() will send the event to all connected sockets.
As I said, this really depends on what exactly you want to do.
EDIT:
Instead of updating your contacts using ajax, you can do that with socket.io.
socket.js
var socketio = require('socket.io');
function init(server) {
var io = socketio(server);
io.on('connection', function (socket) {
console.log("socket connected");
socket.on('newContact', function (data, callback) {
// add data.contactName to db
// after adding something, you use the callback to
// send the added data back to the client
// callback(newContact);
});
});
return io;
}
module.exports = init;
index.html
<script type="text/javascript" >
var socket = io();
// call this emit when the user wants to add a contact
socket.emit('newContact', {contactName: name}, function(newContact) {
// here you will get the result from the server and you can
// update the html with jquery for example
});
</script>
If i understand your question correctly ,maybe you can try this way.
in your routes.js file
var app = require('./app');
var server = require('http').createServer(app);
var io = require('./sockets/my-io')(server);
var route = app.Router();
in your app.js file
var port = process.env.PORT || 3000;
app.listen(port,function(){
console.log('server on port ' + port)
})
I have a node.js application and I am stuck getting an error message when I try to load the homepage. I will do my best at laying out my architecture below. It goes index.js --> server.js --> router.js --> requestHandlers.js
I am using a combination of express (www.expressjs.com) and nodebeginner.org. Sorry for the long question.. just wanted to get as much information down as possible.
index.js (creates handle object that contains pathname/requesthandler information, calls function to start server) I start with router.route here and pass it along each step
var server = require("./server");
var router = require('./router');
var requestHandlers = require('./requestHandlers');
// Routes
var handle = {}
handle['/'] = requestHandlers.home;
server.start(router.route, handle)
server.js (starts the server, THIS IS WHERE I WANT TO CONFIGURE THE SERVER, gets a the pathname from the URL, and passes it on to the route module)
var http = require("http");
var url = require('url');
var express = require('express');
function start (route, handle) {
var onRequest = function(request, res) {
var pathname = url.parse(request.url).pathname;
console.log("request for " + pathname + " recieved.");
route(handle, pathname, res);
}
var app = express.createServer(onRequest).listen(8888);
if (app.configure) {
console.log('app exists'); //logging correctly
}
// Configuration
app.configure(function(){
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(__dirname + '/public'));
});
app.configure('development', function(){
app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});
app.configure('production', function(){
app.use(express.errorHandler());
});
console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env); //logs correct with 8888 and development
}
exports.start = start;
router.js (the function route passed from index --> server which calls the route function in router.js, calls the requestHandler that matches the pathname in handle object)
function route (handle, pathname, res) {
console.log("About to route a request for" + pathname); //About to route a request for/stylesheets/style.css SEE BELOW******* this is the error
if (typeof handle[pathname] === 'function') {
handle[pathname] (res);
}
else {
console.log('no request handler found for' + pathname);
}
}
exports.route = route;
requestHandler.js (interacts with the res/req objects, functions are mapped to certain pathnames, only called when those pathnames are requested thanks to the router)
var home = function(res){
res.render('index', { title: 'WWYB?' });
console.log('homepage rendered'); //correctly logs for pathname = '/'
//click();
};
exports.home = home;
***when i go to request localhost:8888 it tries to make a bunch of requests. first it requests "/" correctly but then keeps going through logging everything saying "About to route a request for/stylesheets/style.css" Eventually the page loads with no css. The pathname as indicated in my layout.jade file is exactly that '/stylesheets/style.css'.
Why is the pathname ever evaluating to /stylesheets/style.css? I think node is doing something in the background and I dont fully understand it.
Let me know if you need more info. Thanks!
Like #TJHolowaychuk commented you really should check the manual, and follow a bunch of tutorials. Anyway, I'll try to help you a bit.
The is a very basic explanation. Express allows you to use sub applications, so you can have different part of you application in different files. It has it's own router too. If you need to do something with the request and/or the response before the route is processed, you can create a middleware. If you want you configurations in a different module, then return a function in it.
So an example of server.js :
var $express = require('express'),
app = module.exports = $express.createServer(),
subapp = require('./subapp'),
configure = require('./configure');
// Each of our own configure returns a function that will be
// called by app.configure
app.configure(configure.all(app));
app.configure('development', configure.devel(app));
app.configure('production', configure.prod(app));
// Use our sub application
app.use(subapp);
// Now listen
app.listen(3030)
subapp.js :
var $express = require('express'),
subapp = module.exports = $express.createServer();
// Add a handler for GET / to our sub-application
subapp.get('/', function (req, res) {
res.end('Hello world!');
});
Finally configure.js :
var $express = require('express');
exports.all = function (app) {
return function () {
// Global configurations
app.use($express.bodyParser());
app.use($express.methodOverride());
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use($express.static(__dirname + '/public'));
//...
// If you want to do something with/on the request/response
// you can create a middleware
app.use(function (req, res, next) {
console.log('caught request %s %s', req.method, req.path);
// Don't forget the callback
next();
});
};
};
exports.devel = function (app) {
return function () {
// Development configurations
};
};
//...
Go to localhost:3030 with your favorite browser, it displays "Hello world!", this is our request handler. If you look at the terminal, you'll see "caught request GET /", this is our middleware.
Your stylesheets, client-side javascripts, etc. should be in /public. app.use(express.static(__dirname + '/public')) will serve these.
Let's say you have /public/stylesheets/all.css, then in your jade template you can include it like this link(rel='stylesheet', href='/public/stylesheets/all.css')
Now, you'll have to experiment and learn more about node and express before even thinking to deploy something to production, these websites may help you:
howtonode
nodetuts
Hope this tiny-micro-tut helps you.
woah this is pretty confusing, you might want to start with the app express(1) can generate for you