server-side changes for $locationProvider.html5Mode(true); - node.js

server code:
app.get('/', function(req, res){
console.log('executed "/"')
res.render('home');
});
app.get('/partials/:name', function (req, res) {
console.log('executed partials:name');
var name = req.params.name;
console.log(name);
res.render('partials/' + name);
});
the code works perfectly before i put $locationProvider.html5Mode(true); to convert '/#/' url into regular / url.
After which, the console.log('executed partials:name'); fails to execute. Documentation says:-
Server side
Using this mode requires URL rewriting on server side, basically you have to rewrite all
your links to entry point of your application (e.g. index.html)
The changes I have tried are not working. What are changes to be made?
Edit: The following is the angular code:
var myApp = angular.module('myApp', []);
myApp.config(['$routeProvider', function($routeProvider, $locationProvider) {
$routeProvider.
when('/', {
templateUrl: 'partials/partial',
controller: 'homePage'
}).
otherwise({redirectTo: '/login'});
$locationProvider.html5Mode(true);
}]);
I again mention, the routing works perfectly well, till i add $locationProvider.html5Mode(true); to angular.

Not quite sure if this matches your problem but when we did this we needed to create a few rules on the server(in Nginx with our setup) to make sure a link to /page didn't just return 404 because it didn't exist on the server.
First we needed to make sure that a link to an Angular route was treated as such. So we do a rewrite ourdomain.com/page to ourdomain.com/#/page. /page doesn't exist on the server, only in Angular, so it would return 404. It needs to go to the index so that Angular can handle the route (this is relevant from incoming links, not so much for when you are on the site since then Angular handles the links anyway).
Secondly we needed to make an exceptions for partials, since those actually actually exists on the server and are not Angular routes. So going to ourdomain.com/partials/partial actually needs to find the partial on the server and can't be rewritten by the above rule.
Hope that helps somewhat at least.

Error is not with routing in this case. myApp.config(['$routeProvider', function($routeProvider, $locationProvider) is defined wrongly.
it should include $locationProvider thus :-
myApp.config(['$routeProvider', '$locationProvider', function($routeProvider,
$locationProvider) {
works perfectly.

Related

Heroku Node/React Deployment Routes Everything to index.html

I have an app.js node main file where I define my api path as the following
app.get('/api/users', UserController.get);
Below in the same file I have the following
app.use(express.static(path.resolve(__dirname, "./front/build")));
app.get("*", function (request, response) {
response.sendFile(path.resolve(__dirname, "./front/build", "index.html"));
});
The index.html successfully serves React App.
If I open my heroku app somewhere at my-app.herokuapp.com it will open the React app which is intended but the Problem is my-app.herokuapp.com/api/users also serves index.html file instead of JSON that the endpoint is supposed to return.
I tried
I replaced endpoint route definition to come before the "" definition (didn't suffice)
EVEN more, I removed redirection to index.html but heroku still opens the index.html page with any type of request (the "" redirection still works). So, it might have cached something?
Is it about cache (how to clean?) or any other suggestions?
You should create routes and work in a proper flow for each functionality,
For Example:
//app.js
app.use("/api/user",userRoutes);
//UserRoutes
router.post("/signup",UserController.signup);
//UserController
exports.signup = async (req,res,next) => {
//Signup function to add a new user when the user provides required info
}
In this way, you code will be easily accessible and much efficient

Express not catching request to '/'

I have a quite bizzare issue - somehow, Express does not capture my request to my root route.
My Route File looks to following:
'use strict';
var errors = require('./components/errors');
var auth = require('./controllers/auth');
var ensureLoggedIn = require('connect-ensure-login').ensureLoggedIn;
module.exports = function(app) {
// Insert routes below
// All undefined asset or api routes should return a 404
app.route('/:url(api|auth|components|app|bower_components|assets)/*')
.get(errors[404]);
app.route('/login')
.get(auth.login)
.post(auth.loginUser);
app.route('/logout')
.get(auth.logout);
// All other routes should redirect to the index.html
app.route('/*')
.get(ensureLoggedIn('/login'), function(req, res) {
console.log("req to /");
res.sendfile(app.get('appPath') + '/index.html');
});
};
So what happens:
I request '/' and it sends me directly to my root and the app runs. Except: It does not require me to login, and also the Log Output does not show that any request has been made.
If i request '/users' (Angular Route) it redirects me to '/login', as expected and then continues on its path.
Any idea what would be causing this behavior?
Are you exposing any static assets with express? If you are and you require your routes after you expose the assets, the request to "/" will just land in your public folder and do nothing.
Does this help? Could you post your server.js?
I ran into this issue earlier and it was driving me nuts.
It seems like it's related to the filename of the 'main' Page being served, before Angular takes over.
Originally, the file was names index.html which, as it seems like, prompted Node to serve it by default - Which is expected behavior, if no routes interfere.
After renaming the main file to application.html and changing the serve asset - all is well, problem solved.
I am still unsure though, why the Route would not fire and the index would overwrite it.

transmission rpc with expressjs

i currently have transmission-daemon web ui served by nginx
server {
listen 2324;
server_name torrent.example.com;
location /rpc {
proxy_pass http://127.0.0.1:9091/transmission/rpc;
}
location /transmission {
proxy_pass http://127.0.0.1:9091/transmission;
}
location / {
proxy_pass http://127.0.0.1:9091/transmission/web/;
}
}
i am trying to display this page via https://github.com/stormpath/stormpath-express-sample this dashboard/user interface
in routes/index.js i have
router.get('/torrent', function (req, res, next) {
if (!req.user || req.user.status !== 'ENABLED') {
return res.redirect('/login');
}
var newurl = 'http://127.0.0.1:2324'
request(newurl).pipe(res)
});
i see the html when i goto /torrent but no images/css/js i am thinking the request is not the right tool for this purpose could some one offer a better solution
many thanks
Your HTML probably refers to CSS/images/etc using URLs such as /index.css. The browser makes these into fully-qualified URLs that look like http://torrent.example.com/index.css, which is not proxied by ngnix the way you have it set up.
You probably want to either use URLs such as /transmission/index.css for your CSS (when specified in the HTML), or alternatively have a <base> tag in your HTML for that.
ok so i have made progress with html/css i moved the transmission interface into the express root and imported the html into jade but now i am having a new problem
when i load the /torrent page i can seen in the web console it makes a request to /rpc which i have made a route for
router.get('/rpc|/rpc/', function (req, res) {
var newurl = 'http://127.0.0.1:9091/torrent/rpc/'
request(newurl).pipe(res)
});
but this comes up with a 404 when i change router.get to router.post i get a 405 error
i have removed the 409 error from transmission so this should work
i have solved the issue
i imported the transmission index.html into a jade template
i routed /torrent to render that template
then i made a new route for /rpc|/rpc/ made that do a post request to the backend transmission-daemon
i also changed /js/remote.js to look for the RPC._Root at the atchual domain

Prerender.io not caching pages

I have made an app with AngularJS with an expressJS backend. Now I want to make it crawlable and I've found prerender.io. I think I've done everything correct bur for some reason I don't see any statistics in the prerenderer dashboard.
In my app.configure function I've included the token like follows:
app.use(require('prerender-node').set('prerenderToken', 'my-token'));
And in my HTML I've included the meta-fragment tag:
<meta name="fragment" content="!">
The last ting I've done was to tell AngularJS to use a hashprefix:
$locationProvider.html5Mode(false);
$locationProvider.hashPrefix('!');
But for some reason, if I refer to the documentation, I don't get the correct result. Below you can see what it is supposed to do:
Google sends a request to your server like this:
http://www.example.com/?_escaped_fragment_=/user/123
You turn the url back into this:
http://www.example.com/#!/user/123
For some reason if I try this it still adds the #! signs add the end of the URL, so if I request the URL of my app like google I get this:
http://www.my-website.com/?_escaped_fragment_=#!/home
So it does not replace the hash in the url. I think this is the cause of my problem.
Thanks in advance!
Edit - if I for example add an extra route then it works:
app.get('/', function (req, res) {
res.sendfile('./public/index.html');
});
app.get('/test', function (req, res) {
res.sendfile('./public/index.html');
});
the '/' route doesn't work the '/test' route does work.
Ok I solved my problem. The '/' route was never called because I had an index.html file inside my webpublic folder. I renamed this to public.html and changed the '/' route to get this file instead of the index.html file.
app.get('/', function (req, res) {
res.sendfile('./public/public.html');
});

How to use AngularJS routes with Express (Node.js) when a new page is requested?

I'm using Express, which loads AngularJS from a static directory. Normally, I will request http://localhost/, in which Express serves me my index.html and all of the correct Angular files, etc. In my Angular app, I have these routes setup, which replace the content in an ng-view:
$routeProvider.when('/', {
templateUrl: '/partials/main.html',
controller: MainCtrl,
});
$routeProvider.when('/project/:projectId', {
templateUrl: '/partials/project.html',
controller: ProjectCtrl,
});
$locationProvider.html5Mode(true);
On my main page, I have a link to <a href="/project/{{project.id}}">, which will successfully load the template and direct me to http://localhost/project/3 or whatever ID I have specified. The problem is when I try to direct my browser to http://localhost/project/3 or refresh the page, the request is going to the Express/Node server, which returns Cannot GET /project/3.
How do I setup my Express routes to accommodate for this? I'm guessing it will require the use of $location in Angular (although I'd prefer to avoid the ugly ?searches and #hashes they use), but I'm clueless about how to go about setting up the Express routes to handle this.
Thanks.
with express 4, you probably want to catch all requests and redirect to angularjs index.html page.
app.use(app.router); doesn't exist anymore and res.sendfile is deprecated, use res.sendFilewith an uppercase F.
app.post('/projects/', projectController.createProject);
app.get('/projects/:id', projectController.getProject);
app.get('*', function (req, res) {
res.sendFile('/public/index.html');
});
put all your API routes before the route for every path app.get('*', function (req, res){...})
I would create a catch-all handler that runs after your regular routes that sends the necessary data.
app = express();
// your normal configuration like `app.use(express.bodyParser());` here
// ...
app.use(app.router);
app.use(function(req, res) {
// Use res.sendfile, as it streams instead of reading the file into memory.
res.sendfile(__dirname + '/public/index.html');
});
app.router is the middleware that runs all of your Express routes (like app.get and app.post); normally, Express puts this at the very end of the middleware chain automatically, but you can also add it to the chain explicitly, like we did here.
Then, if the URL isn't handled by app.router, the last middleware will send the Angular HTML view down to the client. This will happen for any URL that isn't handled by the other middleware, so your Angular app will have to handle invalid routes correctly.
I guess I should have clarified that I wasn't interested in using a template engine, but having Angular pull all of the HTML partials on it's own, Node is functioning completely as a static server here (but it won't be for the JSON API. Brian Ford shows how to do it using Jade here: http://briantford.com/blog/angular-express.html
My app is a single-page app, so I created an Express route for each possible URL pattern, and each of them does the same thing.
fs.readFile(__dirname + '/public/index.html', 'utf8', function(err, content) {
res.send(content);
});
I was assuming I would have to pass some request variables to Angular, but it looks like Angular takes care of it automatically.

Resources