How to use vuejs routing with history fallback and expressjs routes - express

I've been stuck on this for a number of weeks and I can't figure it out. It's driving me crazy... Ive read numerous tutorials and it sounds like it's something that should work!
I have an expressjs server setup and a vuejs app. I want to be able to serve the vuejs routes with history browser mode and I also want to be able to setup server side routes for my api layer.
If I disable the history mode, everything works ok - but I need to enable history mode, so that I can use auth0 library and callbacks. Callbacks do not allow # in the url.
Here is my code:
const express = require('express');
const path = require('path');
const bodyParser = require('body-parser');
const logger = require('morgan');
const history = require('connect-history-api-fallback');
const app = express();
app.use(require('connect-history-api-fallback')())
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(history({
verbose: true
}));
app.get('/api', (req, res) => res.send('Hello World!'))
app.use('/', express.static(path.join(__dirname, 'dist')));
var port = process.env.PORT || 8080;
app.listen(port);
console.log('server started '+ port);
For the code above, the vuejs app is sitting under /dist and all the routes for that one work. But when I try to hit /api - it is also being redirected to the vuejs app.
Any help would be greatly appreciated! I'm at the point where I'm thinking its just not possible.

I was having the same issue. I fixed it by adding app.use(history()) after my api routes, but before app.use('/', express.static(path.join(__dirname, 'dist')));.
So I think for you it'd be like
const express = require('express');
const path = require('path');
const bodyParser = require('body-parser');
const logger = require('morgan');
const history = require('connect-history-api-fallback');
const app = express();
app.use(logger('dev'));
app.use(bodyParser.json());
app.get('/api', (req, res) => res.send('Hello World!'));
app.use(history({
verbose: true
}));
app.use('/', express.static(path.join(__dirname, 'dist')));
var port = process.env.PORT || 8080;
app.listen(port);
console.log('server started '+ port);
This answer helped me: https://forum.vuejs.org/t/how-to-handle-vue-routes-with-express-ones/23522/2

Related

Switching from working node js socket io serialport to node express router how to?

I am new to node express (started with node long time ago but didn't do much) and I would like to learn how to use it. I am going through some of my older work and reading lots of tutorials but I just can't seem to get this one working.
I have this app that reads data from some sensors on serial port and sends it to sesors.ejs. I would like to reprogram it in express. I have the sensor reading in terminal but not in ejs.
old (working) app.js
var http = require('http');
var fs = require('fs');
var url = require('url');
var path = require('path');
const { SerialPort } = require('serialport')
const { ByteLengthParser } = require('#serialport/parser-byte-length')
const port = new SerialPort({ path: 'COM4', baudRate: 9600 })
const parser = port.pipe(new ByteLengthParser({ length: 30 }))
var sensors = fs.readFileSync('views/sensors.ejs');
var app = http.createServer(function(req, res){
res.writeHead(200, {'Content-Type':'text/html'});
res.end(sensors);
});
var io = require('socket.io').listen(app);
io.on('connection', function(data){
console.log
});
parser.on('data', function(data){
console.log(data.toString("UTF8"));
io.emit('data', data.toString("UTF8"))
});
app.listen(3000);
old (working) sensors.ejs
<script>
var socket = io();
socket.on('data', function(data){...}
</script>
This works great.
I went through several express routing tutorials but I don't know how to send io data to router.
I have c/p most of the code from old app.js to new sensor.js in routes dir, without fs, app.listen etc. I have c/p sensors.ejs to views folder.
In new app.js I have:
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var sensorsRouter = require('./routes/senzori');
var app = express();
app.set('views', path.join(\__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(\__dirname, 'public')));
app.use('/', indexRouter);
app.use('/users', usersRouter);
app.use('/senzori', sensorsRouter);
index.ejs and users.ejs (fetch mysql data) are working (express is installed and working)
Thanks
I have found the solution. If anyone else with my level of "knowledge" needs the solution, here it is:
I have moved reading serial port to bin/www
The only code in sensors.js is:
router.get('/', function(req, res, next) {
res.render('sensors');
});

Login/register not working when website deployed to Heroku

I have an express app that has been working fine on localhost:3000, and the mongoDB cloud database is also successfully connected, but when I deployed to Heroku the login and register timed out.
I got error code=h12 which is a timeout error. I wanna know if there is anything I am missing, or if I should use a different login/register plugin. Currently using passportJS and Passport-Local-Mongoose.
const express = require('express');
const mongoose = require('mongoose');
const ejs = require('ejs');
const bodyParser = require('body-parser');
const session = require('express-session');
const passport = require('passport');
const passportLocalMongoose = require('passport-local-mongoose');
const Chart = require('chart.js');
const ObjectId = require('mongodb').ObjectID;
const password = process.env.PASSWORD;
const Schema = mongoose.Schema;
const app = express();
app.set('view engine', 'ejs');
app.use(bodyParser.urlencoded({extended: true}));
app.use(express.static('public'));
app.use(session({
secret: "null",
resave: false,
saveUninitialized: false
}));
app.use(passport.initialize());
app.use(passport.session());
userSchema.plugin(passportLocalMongoose);
const User = mongoose.model('User', userSchema);
passport.use(User.createStrategy());
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
app.post('/register', (req, res)=>{
User.register({username: req.body.username},
req.body.password, function(err, user){
if (err){
console.log(err);
res.redirect('/register');
} else {
passport.authenticate('local')
(req, res,function(){
res.redirect('/home');
});
}
});
});
If you have any environmental variables locally, you also need to add those variables in Heroku too. Go to your heroku control panel, go to settings, and then click on Reveal config vars. There, you add your Key value pairs

app.js code comparison because ejs not working

I'm using express.js and ejs.
I will post below two codes for the app.js file. The thing is that ejs and layout.ejs do not work with the one of those two codes, but it works perfectly with the other
Here are the two codes:
The first one, which ejs is working:
const express = require('express');
const expressLayouts = require('express-ejs-layouts');
const path = require('path')
const app = express();
// Bodyparser
app.use(express.urlencoded({extended:false}));
/// EJS
app.use(expressLayouts);
app.set('view engine', 'ejs');
//PUBLIC FOLDER(css and js)
app.use(express.static(path.join(__dirname,'/public')));
// Express body parser
app.use(express.urlencoded({ extended: true }));
// Routes
app.use('/', require('./routes/index.js'));
app.use('/users', require('./routes/users.js'));
const PORT = process.env.PORT || 5000;
app.listen(PORT, console.log(`Server started on port ${PORT}`));
and the second one, which ejs is not working:
const express = require('express');
const app = express();
const PORT = process.env.PORT || 5000;
const expressLayouts = require('express-ejs-layouts');
const mongoose = require('mongoose');
const path = require('path')
// Bodyparser
app.use(express.urlencoded({extended:false}));
//ROUTES
app.use('/', require('./routes/index'))
app.use('/users', require('./routes/users'))
// EJS
app.use(expressLayouts);
app.set('view engine', 'ejs');
app.set('view options', { layout:'layout.ejs' });
//PUBLIC FOLDER(css and js)
app.use(express.static(path.join(__dirname,'/public')));
//DB CONFIG
const db = require('./config/keys').MongoURI;
// //Connect to mongo
mongoose.connect(db, {
useNewUrlParser: true,
useUnifiedTopology: true
}).then( () => console.log('MongoDB Connected...'))
.catch( err => console.log(err));
app.listen(PORT, console.log(`Server started on PORT ${PORT}`));
I'm trying to figure out what's the issue with the second code and doesn't make the ejs work. Can anyone have a quick glimpse and compare these two and tell me what's the problem? Thank you for your time

Mean Stack Root Routing is not working

Can someone help me why default route is not working in my Mean App, But the next routing works
Here when I open http://localhost:3000 I am not able to see any output, But I have defined route in route.js which is working
var express = require('express');
var cors = require('cors');
var bodyparser = require('body-parser');
var mongoose = require('mongoose');
var path = require('path');
const port = 3000;
app.get('/', function (req, res) {
res.send('Test');
console.log('Opened the root path');
});
When I open the page with http://localhost:3000/main I am able to see the Output and also log written in the console
const express = require('express');
const router = express.Router();
router.get('/main', function (req, res, next) {
res.send('This is the Admin Landing Page');
});
router.get('/install', function (req, res, next) {
res.send('This is the Install Landing Page');
console.log('Opened the Install path');
});
module.exports = router;
It looks like you the code you pasted is the full version, and it's not runnable because:
You did not declare app variable.
You did not start the http server.
It's really hard to tell the root cause what's wrong of your code. Following codes works for me:
const express = require('express');
const port = 3000;
let app = express();
app.get('/', function (req, res) {
res.send('Test');
console.log('Opened the root path');
});
let server = require('http').createServer(app);
server.listen(port, function() {
console.log('Server started');
});

router vs app in express 4.0

I am learning express js 4.0 and building compact CRUD REST API web application with it. In the tutorial, it shows two ways; using app and using router.
//using router
var router = express.Router();
router.get('/', function(req,res){
res.send('hello, world')
});
//using app
app.get('/', function(req,res){
res.send('hello, world')
});
To me, I feel they work same but I don't know why people use router, I think using app is more simple. Can anybody explain what is difference between them?
It allows for modularity. A lot of people have a routes folder that they keep all their route handlers in. And then in their app.js file, they just do something like app.use(<prefix>, <routes>); after they require their router. It keeps your files smaller and more organized.
Example:
app.js
var express = require('express');
var rootRoutes = require('./routes/index');
var userRoutes = require('./routes/user');
var app = express();
app.use('/', rootRoutes);
app.use('/user', userRoutes);
module.exports = app;
routes/index.js
var express = require('express');
var router = express.Router();
router.get('/', function(req, res) {
res.render('index.jade');
});
router.get('/about', function(req, res) {
res.render('about.jade');
});
module.exports = router;
routes/user.js
var express = require('express');
var router = express.Router();
router.get('/:name', function(req, res) {
var userName = req.params.name;
res.render('user.jade', {
userName: userName
});
});
module.exports = router;