Express 4 + Angular 2 HTML 5 Routing Concerns - javascript

I am making a basic web app with Express 4 and Angular 2. Here, there is nothing specific to Angular 2 besides the fact I am using its HTML 5 router.
Here is the routing work flow of the app:
There are two main server side routing configurations of the app. Both look similar to this:
/* GET home page. */
router.get('/', authenticationHelpers.isAuth, function(req, res, next) {
res.render('index');
});
/* GET login page. */
router.get('/login', authenticationHelpers.isNotAuth, function(req, res, next) {
res.render('login');
});
These manage explicitly, the two cases in which a user routes to / and /login.
However if the user is logged in and is able to visit / to render the index express view, there are HTML5 routes the user can take advantage of. These include urls like the following:
localhost:5000/user
localhost:5000/profile
localhost:5000/profile/settings
The issue
Clearly there is no router.get('/user'), and there shouldn't be, as this is all front-end work done by the Angular 2 router. However, to enable linking that would allow a user to simply type localhost:5000/profile/settings, and have the site route you to the index file (given that you were logged in) and THEN route you (with angular 2's HTML 5 routing) to your own /profile/settingsI had to place this piece of code in my app.js:
app.all("/*", function(req, res, next) {
res.render('index');
});
This gives me a big problem though. If you are not logged in and you are given the link localhost:5000/profile/settings it will render the index view because it only runs the authenticationHelpers.isAuth function on the router.get('/') routing code above. I would also love to be able to throw 404 errors on routes that don't exist in express, or angular.
However in my mind, to enable this functionality express would have to know about all the HTML 5 routing options as well as the express routing options. To me, this breaks the separation of routing concerns because if I changed an HTML 5 angular route, I'd also have to make a change in express (most likely, view the solution below). I'd like all this functionality, but without this information leaking between route handlers however I simply don't see a way around it. If anyone could help me figure out a better way to do this that would be great! If the information sharing or angular routes with express routes is the only way I've developed the most optimized lean solution I could below:
Potential Solution
router.get(['/', '/user/', '/profile/*'], authenticationHelpers.isAuth, function(req, res, next) {
res.render('index');
});

Add this to the end of all routes
app.all("/*", authenticationHelpers.isAuth, function(req, res, next) {
res.render('index');
});
Should solve your problem

Related

Getting dynamic route url with Express JS causes favicon to disappear

I'm using express.Router(). Getting a dynamic route in the following way causes my favicon to disappear. (Where id is the dynamic part).
router.get('/collab/:id', isAuthenticated, function(req, res) {
Getting a non-dynamic route like this allows my favicon to load properly, all other things being equal.
router.get('/collab', isAuthenticated, function(req, res) {
Somehow in going from :id to the actual value, it forgets to include the favicon. Can't find similar questions using Google. Am I overlooking something?

Using module export to mimic app.post and app.get

The application that I'm currently working on has been a bit difficult to apply information I've gotten from tutorials to. This app uses Express, but also features a lot of proprietary middleware that I don't quite fully understand.
My question relates to a particular way of utilizing app.get and app.post in our application. There isn't really a single point anywhere in the app that we use either of those things in that particular way, instead, each controller that we use features a module.export with GET and POST as the keys, which then contains all the code you would want to use for each request. All of this is wrapped up in a middleware that's based off of Tower.js (basically links the controllers to the views based on file path and name).
This has proved to be a bit troubling with trying to interpret tutorials where the code uses something like
router.post('/s3', multer({ dest: './uploads/'}).single('upl'), function(req, res, next){
client.putFile(req.file.path, '/user.jpg', function(err, response){
if (err) console.log(err)
res.status(200).send({url: response.req.url})
});
Is there any way to re-interpret this if the POST function in my controller for my route is used like this?
module.exports = {
get: function(req, callback){},
post: function(req, callback){}
}
(P.S. Yes, I'm having trouble using multer to upload images to S3 within this application)

"Double vision" with HTML5mode, Angular with ui router and Express

I am an absolute noob, so bear with me. I am developing an app with angular and express. I am using ui.router for the angular routing and express to serve the pages.
I've used the following lines to enable html5 mode, which has successfully removed the pound sign (#) from the urls, however when hitting f5, only the view gets loaded, and not the index which should wrap the view.
$locationProvider.html5Mode(true).hashPrefix('!');
$urlRouterProvider.otherwise('home');
I tried adding the following lines as suggested online, but now the ui router is loading the index page itself in the view (looks like 2 layers of an infinity mirror, if that makes sense).
router.all("/*", function(req, res) {
res.render("index", { user : req.user });
});
I've seen res.sendfile used in examples, but I haven't had any success with that, either.
How can I use Angular's ui router, and express in html5mode without breaking my page? I can gladly give more code if needed.
Edit: more info!
Express serves the index page when '/' is requested.
router.get('/', function (req, res) {
res.render('index', { user : req.user });
});
The index page simply contains
""
which in turn shows the contents of which view I want to show.
EDIT: I have uploaded my project to github. https://github.com/shhtephe/SurfacingSolutions
The files I think you'll most need to see are routes/index.js and views/index.ejs
Hope that helps.

How to pass page index.html and the req.params.id back to the client

I'm using express and Angular. I want to send the page (index.html) and one paramter that will be the ID used to determine which youtube video to load in that page.
app.get('/:id', function(req, res){
//send index page + extractYoutubeVideoCode(req.params.id)
res.sendFile(__dirname + '/index.html')
});
I'm not sure I want to use a template render engine like jade if I've got angular on the front end - but maybe that's the answer
I suspect I can't use # routes with angular as people will be reaching the pages with a link like localhost:3000/TUj0otkJEBi
How should I go about passing the page index.html and the req.params.id back to the client
Will you can use the ui-router plugin to anguler to do this. It helps to navigate in states same as we can do that in backbone and jade but it is not an overhead but can be used as an integral part of angular.
please look here for more details feel free to reply if you find problem in my solution or you need something else.
https://github.com/angular-ui/ui-router/wiki

How to set user name as local variable available in all views in mean.io

I am using mean.io but for my reasons I cut out all the angular it has and replace with knockout.js. Also I want to notice that my application is not single page. I render pages from different views and require for each require.js module with knockout business logic.
That's about app I deal with and here is my problem.
For example if user is logged in I want to show his name in the header of my app. So, I need to set express app.locals after passport creates user session. The problem is I have no idea where does it happen. I find passport initialization, but don't know how to ger user name without using req.user object. So, what is the best way of doing it
Use a middleware.
app.use(function(req, res, next) {
req.user && (app.locals.user = req.user)
});

Categories