Is it possible to route api calls in different files with angular? - angularjs

I cant get my mind straight about routing of api calls with angularjs and express(ie nodejs). I set up the routing in my server as below:
require('./app/routes')(appExpress, passport);
I will have three collections in my database. I need to set upp calls to the api for all the collections in my routes file as below:
module.exports = function(app, passport) {
app.get('/api/compititions', function(req, res) {
Comps.find(function(err, comps) {
console.log(comps);
if (err)
res.send(err);
res.json(comps);
});
});
app.get('/api/swimers', function(req, res) {
// Add code to do something
});
app.post('/api/swimers', function(req, res) {
// Add code to do something
});
// all other calls
app.get('*', function(req, res) {
// send the rest of the calls to the app
});
}
The problem is that adding calls and code for 15 ish calls will become a very LONG file. I would like to separate these calls to different files or in some way make this file readable. Is that good practice or am I on the wrong path?
Thanks for the help and guidance!

Related

Send axios put request to multiple end points by path to express server

I am trying to send an axio put request from my react component to my express server.
my code looks like this at the moment:
axios.put(`http://localhost:3001/restaurants/${targetId}`
and my server side looks like this:
app.use('/restaurants');
const router = express.Router()
router.put('/:id', (req, res)=>{
//perform update here
});
and this works.
but I would like to change my route to this:
axios.put(`http://localhost:3001/restaurants/removeFromFavourite/${targetId}`, {comment, 'too spicy'})
or this
axios.put(`http://localhost:3001/restaurants/addToFavourite/${targetId}`, {comment, 'test great!'})
How should I modify my router so that on express server so that
I have one end point for removeFromFavourite and one end point for addToFavourite.
parse the comment data.
I tried adding the following:
router.put('/removeFavourite/:id', (req, res)=>{
});
router.put('/addToFavourite/:id', (req, res)=>{
});
but they all went to
router.put('/:id', (req, res)=>{
//perform update here
});
thanks

node redirect not working on angular

hi I'm new to node and I'm building a simple MEAN stack app, to reduce the code I'm sending front end files like this
app.use(express.static(path.join(__dirname, 'public')));
i have also build a simple middleware for simple authentication
requireLogin = function (req, res, next) {
if (!req.user) {
console.log('redirecting :)');
res.redirect('/');
} else {
next();
}
};
app.use('/rooms',requireLogin);
I'm trying to use this middleware on routes made in angular.
but this is not working when i navigate through my angular app (it works when i directly put the URL to the address bar) i have also removed the /#/ which is added by angular.
$locationProvider.html5Mode({
enabled: true,
requireBase: false
});
I'm using ui-router for routing.
You should do redirecting on angular, but not on node.js application. For example,
requireLogin = function (req, res, next) {
if (!req.user) {
console.log('User does not exist.');
return false;
//
} else {
next();
}
};
app.use('/rooms', requireLogin);
Then, /rooms won't be able to access unless there is user logged-in.
Backend routes (express ones): Those are the routes that an end user won't have to know about or even use them (your angular app will use them to communicate with the backend to work with its data but an end user wouldn't put them directly on the browser)).
Frontend routes (angular ones): Are the routes that maps to different pages of your application and because of that, end users can use them to access some parts of your application directly.
Read Express.js or angular for handling routes in a MEAN application? for more details.

NavBar address loading angular template but not root shell

I am using Node.JS with Express, Angular.JS and the node module connect-roles for ACL. I want to allow a user with user.status of "Platinum" to access "Platinum" but not "Gold" and vice versa.
I have the ACL part working, if I enter /Platinum into the navigation bar I can't access /Gold, but when I try to access /Platinum I only get the template but not the root shell, so what comes up is this:
You made it!
You have the {{status}} status!
If I click on a link in angular to /Platinum, everything works as it should. If I enter any neutral address in the navigation bar, everything works as it should.
This should be an easy fix, but I've not figured it out.
Here is the code that sets up authorizations, I'm pretty sure everything here is okay.
ConnectRoles = require('connect-roles')
var user = new ConnectRoles({
failureHandler: function(req, res, action){
var accept = req.headers.accept || '';
res.status(403);
if(accept.indexOf('html')) {
res.render('access-denied', {action: action});
} else {
res.send('Access Denied - You don\'t have permission to: ' + action);
}
}
});
var app = express();
app.use(user.middleware());
// Setting up user authorizations,
// i.e. if req.user.status = "Platinum", they are given Platinum status
user.use('Platinum', function(req) {
if (req.user.status == 'Platinum') {
return true;
}
});
user.use('Gold', function(req) {
if (req.user.status == 'Gold') {
return true;
}
});
user.use('Admin', function(req) {
if (req.user.status == 'Admin') {
return true;
}
});
That sets up authorizations, now the problem lies below with the routing.
app.post('/login', passport.authenticate('local',
{ successRedirect: '/', failureRedirect: '/login' }));
app.get('/Platinum', user.is('Platinum'), function(req, res) {
//Obviously the code below is wrong.
res.render('templates/support/Platinum');
});
app.get('/Gold', user.is('Gold'), function(req, res) {
res.render('templates/support/Gold');
});
The way you are configuring your routes on server side (using express) is not correct. For a single page app like AngularJS, you need to do all of the routing for pages on the client (i.e. in Angular). The server still defines routes for API requests (e.g. getting and posting data) and static resources (index.html, partial HTML files, images, javascript, fonts, etc), though.
Thus the following code is wrong in your server side JS:
app.get('/Platinum', user.is('Platinum'), function(req, res) {
//Obviously the code below is wrong.
res.render('templates/support/Platinum');
});
app.get('/Gold', user.is('Gold'), function(req, res) {
res.render('templates/support/Gold');
});
Just remove those lines.
Instead, you need to define the routes that the server will handle, such as your /login post one first, and how to get static files (I suggest prefixing them all with /pub in the URL). Then you need to do something like the technique in this answer to return your index.html page if no routes are matched.
That way, when a user types http://localhost:port/Gold, express will see there is no route defined for /Gold, so it will return index.html, which will load AngularJS, run your Angular app, which will then look at the URL and see if that matches any of the routes your AngularJS app has configured, and if so, fetch the partial for that page and insert it into your ng-view (if using the core router).

Express app.all interfering with API calls

I'm building a MEAN app and Angular is handling any routes that are defined by the client such as '/profile', '/stream' etc.
Because I'm using HTML5Mode in Angular, I've had to add the following to my express config to allow clean URLs to be accessed and input from browser URL bar:
app.all('/*', function (req, res, next) {
res.sendfile('views/dashboard.html', { root: __dirname });
});
This however is now interfering with my API and any API calls are returned blank, so for example if I visit users/active/profile which should return a JSON response of the current user's details, the browser redirects you to the homepage.
Express will handle the requests URLs(routes) in the order you declared them, since * is an exception to all other previous route declarations you need to move this code to the end of your routes:
/** this needs to be your last route **/
app.all('/*', function (req, res, next) {
res.sendfile('views/dashboard.html', { root: __dirname });
});

Authentication when using angularjs and passportjs

I am currently using passportjs for authenticaton.
I have come across a stage where i need to ensure the user is authenticated if the url is typed in the browser/ I have been using the passportja example which has the following:
app.get('/admin', ensureAuthenticated, function(req, res){
console.log('get admin');
res.render('admin', { user: req.user });
});
function ensureAuthenticated(req, res, next) {
if (req.isAuthenticated()) { return next(); }
res.redirect('/login')
}
I am using angularjs for routing so my get does not work and run the ensure authenticated.
How should this be implemented?
With AngularJS, you need to restrict the display of templates to the user.
So, let us say you have the following code in AngularJS:
$routeProvider.when('/admin', {
templateUrl: '/partials/admin-page.html'
});
When the user tries the /admin route, AngularJS will then request the template /partials/admin-page.html.
Thus, in your nodeJs server, you then implement the following code:
app.get('/partials/admin-page.html', ensureAuthenticated, function (req, res) {
res.render('admin', { user: req.user});
});

Resources