router .use() requires a middleware function but got a string - ejs

I am using EJS for templating, when I add this
app.use("view engine","ejs")
in my code i get error.
router .use() requires a middleware function but got a string
The rest of the code:
const express = require('express');
const bodyParser = require('body-parser');
const port = 3000;
const app=express();
app.use("view engine","ejs");
app.get('/', function(req, res){
var today = new Date();
var currentDay = today.getDay();
var day ="";
if(currentDay === 6 || currentDay === 0){
day ="weekend";
}else{
day = "weekday";
}
res.render("list",{kindOfDay:day});
});
app.listen(port, function(){
console.log('The server has started');
});

Look at the documentation for using template engines:
app.set('view engine', 'pug')
use is used to add middleware, and a string isn't middleware, hence the error message.
You need to use set to set a setting.

Related

mongoDB, mongoose, cannot connect to DB

First time using mongoDB. Trying to connect to my cluster that i just created on atlas however i keep getting errors
keys.jss
module.exports = {
mongoURI: 'mongodb+srv://john:<********>#mern-shopping-i5abd.mongodb.net/testretryWrites=true&w=majority'
};
I might be following an outdated tutorial so certain things might be 'unnecessary'
const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const app = express();
// Bodyparser Middleware
app.use(bodyParser.json());
// DB config
const db = require('./config/keys').mongoURI;
// Connect to Mongo
mongoose
.connect(db, {useNewUrlParser: true} )
.then(() => console.log('monogoDB Connected...'))
.catch(err => console.log(err));
const port = process.env.PORT || 5000;
app.listen(port, () => console.log('Server started on port ${port}'));
Rather than displaying port '5000' i would get an error (different each time)
message: '3rd parameter to mongoose.connect() or mongoose.createConnection() must be a function, got "object"',
name: 'MongooseError'
Here is how it would look with a function as a callback, instead of using promises. Notice that I also moved the app startup inside the callback function. This ensures that the app only starts up when we successfully connect to the DB.
I also moved the DB options (2nd parameter in the connect method), into a variable. This way, it's easy to find and can be modified in one place, if necessary. Ideally, you'd keep all your DB config in a single file, and reference it in other files as needed. Separate concerns :)
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const app = express();
// Bodyparser Middleware
app.use(bodyParser.json());
// DB config
const db = require('./config/keys').mongoURI;
const dbOptions = {useNewUrlParser: true, useUnifiedTopology: true};
// Connect to Mongo
mongoose
.connect(db, dbOptions, function(error) {
// we had an error of some kind
if (error) {
console.error(error);
// better yet, we don't want to app to run without our DB!
throw error;
}
// If we made it here, no errors came up
console.log('monogoDB Connected...');
// Start up the app!
const port = process.env.PORT || 5000;
app.listen(port, () => console.log(`Server started on port ${port}`));
});
Here is how it would look with the promise structure:
const express = require( "express" );
const mongoose = require( "mongoose" );
const bodyParser = require( "body-parser" );
const app = express();
// Bodyparser Middleware
app.use( bodyParser.json() );
// DB config
const db = require( "./config/keys" ).mongoURI;
const dbOptions = {useNewUrlParser: true, useUnifiedTopology: true};
// Connect to Mongo
mongoose
.connect( db, dbOptions )
.then( () => {
console.log( "monogoDB Connected..." );
// Start the application
const port = process.env.PORT || 5000;
app.listen( port, () => {
console.log( `Server started on port ${port}` );
} );
} )
.catch( err => {
console.log( err );
throw err;
} );

status 503 when heroku node app try to access to mlab db add-on with monk

I'm trying to deploy my express-mongodb app on heroku. I've already tryed to access locally to the heroky mlab addon and with the local server works fine. But when I start the same server on heroku it looks like the server can't solve the requests because of the db lack. I'm wondering if the problem is with monk js or something else.
<!-- language: lang-javascript-->
const express = require('express');
const bodyParser = require('body-parser');
const monk = require('monk');
const engines = require('consolidate');
const app = express();
const router = require('./routes/router');
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static(`${__dirname}/public`));
app.set('views', `${__dirname}/templates`);
app.engine('html', engines.mustache);
app.set('view engine', 'html');
const db = monk('mongodb://<xxxx>.mlab.com:15338/heroku_1xx37v0b');
db.then(() =>{
console.log("connection success");
}).catch((e)=>{
console.error("Error !",e);
});
app.use((req, res, next) => { req.db = db; next(); });
app.use('/', router);
app.listen(process.env.PORT || 3000);
// ask something to the db
const collection = db.get('docUtenti');
collection.findOne({type: "docTotUtenti" }).then((doc) => {console.log(doc);})

cannot GET / express.js routing

I am at the early stages of a simple tasks manager that I want to build with the MEAN Stack.
I can figure/resolve a simple routing issue. I don't see any error message in the terminal or console except for the 404 client error.
the root path is ok. I get a response back
I use html docs to render the ui for both.
this is how I have set up my server.js
var express = require('express')
var path = require('path')
var bodyParser = require('body-parser')
var index = require('./routes/index');
var tasks = require('./routes/tasks');
var app = express();
const port = '3456'
app.use('/', index)
app.use('api', tasks) <= HERE
//view engine
app.set('views', path.join(__dirname, 'views'))
app.set('view engine', 'ejs')
app.engine('html', require('ejs').renderFile);
//static folder
app.use(express.static(path.join(__dirname, 'client')))
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({extended: false}))
app.listen(port, function() {
console.log('Starting the server at port' + port );
})
tasks.js
to render the template at the set route
var express = require('express')
var router = express.Router();
var mongojs = require('mongojs');
var db = mongojs('mongodb://sandy:cookie2080#ds147304.mlab.com:47304/tasklists_21092017', ['tasks'])
router.get('/tasks', function(req, res, next) {
res.send('api')
res.render('tasks.html')
db.tasks.find(function(err, tasks){
if (err) {
res.send('error message ' + err)
}
res.json(tasks)
})
})
module.exports = router;
and, index.js fyi
var express = require('express')
var router = express.Router();
router.get('/', function(req, res, next) {
res.render('index.html')
})
module.exports = router;
screenshot at the link below of the 404 error in browser after starting server on port 3456
404 error - screenshot
thanks for the help. I am sure it can be a little detail. it is very hard to debug though.
This error occurs because there's no route that handles the endpoint /api. What you can do here is create a middleware that will handle the /api. You can do it in your tasks.js like this:
tasks.js
router.get('/', function(req, res, next) {
res.send('This is api.')
})
Or if what you want to do is to direct the user from the endpoint /api to /api/tasks then you could do it like this:
router.get('/', function(req, res, next) {
res.redirect('/api/tasks')
})
Hope this helps.
I changed the port number. The issue was that the port 3000, was not responding to the requests, as it was still in use by an older process hence producing the warning
errno: 'EADDRINUSE',.
Just used the port 5000 to try out and it went through smoothly.
By the way I am using vs code.

Use socket.io with HTTPS instead of HTTP

I am using self-signed certificated to encrypt traffic data.
My .crt and .key files are located at /etc/nginx/ssl/
(some_file.key and some_file.crt)
I was using socket.io over http but tried to get it over to https. Here is my actual code:
var formidable = require('formidable');
var express = require('express');
var fs = require('fs');
var privateKey = fs.readFileSync('../etc/nginx/ssl/some_file.key').toString();
var certificate = fs.readFileSync('../etc/nginx/ssl/some_file.crt').toString();
//how can I exclude this? (I have no intermediate, should I?)
var ca = fs.readFileSync('../intermediate.crt').toString();
var app = express.createServer({key:privateKey,cert:certificate,ca:ca });
var io = require('socket.io');
app.listen(3000, function(){
//wait on 3000
});
app.post('/posts', function(req, res){
//server communication
});
io.on('connection', function(socket){
//wait on connections
});
Client-side:
var socket = io(url + ":3000", { "secure": true, 'connect timeout': 5000 });
Is this the correct way to do it? I based my https code on examples, so I'm doubting on whether this is well enough (I know it isn't, but should be close). When I run the code, I also get an error no such file or directory '../etc/nginx/ssl/some_file.key'...
I use it this way, although this is very dependent on express version you are using. This is for version 3.4
var express = require('express')
, app = express()
,fs = require('fs')
,events = require('events');
...
var options = {
key: fs.readFileSync('/etc/nginx/ssl/some_file.key'),
cert: fs.readFileSync('/etc/nginx/ssl/some_file.crt')
};
/*
*Configuration
*
*/
var server = require('https').createServer(options, app), io = require("socket.io").listen(server);
var port = 8443;
var ipaddr = '0.0.0.0';
app.configure(function() {
app.set('port', port);
app.set('ipaddr', ipaddr);
app.use(express.bodyParser());
app.use(express.methodOverride());
...
});

Blog created with ExpressJS backed by MongoDB not showing posts from DB

I've created a very simple blog web app with ExpressJS and MongoDB. But the index page doesn't render the 'blogPosts' that I input into the DB. It only shows the title as "BL's Blog", without any posts below.
Why aren't the posts showing?
app.js:
//Module dependencies
var express = require('express');
var routes = require('./routes');
var user = require('./routes/user');
var http = require('http');
var path = require('path');
//Mongodb
var mongo = require('mongodb');
var monk = require('monk');
var db = monk('localhost:27017/hello-express/');
var app = express();
// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
// development only
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
//GET
app.get('/', routes.index(db));
app.get('/users', user.list);
app.get('/userlist', routes.userlist(db));
app.get('/newuser', routes.newuser);
//POST
app.post('/adduser', routes.adduser(db));
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
routes/index.js(I only included exports.index as it's the relevant route to this problem):
exports.index = function(db) {
return function(req, res) {
var posts = db.get('blogPosts');
posts.find({}, {}, function(e, docs) {
res.render('index', {
"index": docs
});
});
};
};
views/index.jade:
extends layout
block content
h1.
BL's Blog
ul
- each post in index
li
h3 = post.title
p = post.content
Ok now I have actually found out the answer to my own question, thanks to the help of WiredPrairie.
The first problem lies with the name of the database that I'm using. Thus in my index.js, it should have been:
exports.index = function(db) {
return function(req, res) {
var posts = db.get('hello-express'); //Here's the difference.
posts.find({}, {}, function(e, docs) {
res.render('index', {
"index": docs
});
});
};
};
I listed in app.js that I'm using the database called 'hello-express' with this line below:
var db = monk('localhost:27017/hello-express/');
Hence the name of database being used should be named as 'hello-express'.
However, even after doing so, I could not render the Jade page properly. This was due to a syntax error (I know, I'm new.)
extends layout
block content
h1.
BL's Blog
ul
- each post in index
li
h3 #{post.title}
p #{post.content}
By using #{<var>} instead of =, the page was able to render properly. I still have no idea why this is the case, but at least it has solved my problem for now.