Trouble with $routeProvider in page served by Express.js - javascript

I am trying to build my first Express.js/Angular application but am having trouble with $routeProvider on the page being served by the Express.js application. Here is the server.js:
var express = require('express');
var PORT = process.env.PORT || 3000;
var app = express();
app.get('/', function (req, res) {
res.sendFile(__dirname + '/client/views/index.html');
});
app.listen(3000, function () {
console.log("I'm listening");
});
The index.html page renders and includes the following Angular code:
var app = angular.module('app', ['ngRoute']);
app.config(function ($routeProvider) {
$routeProvider
.when('/main', {
templateUrl:'/client/views/main.html'
});
});
Yet when navigating to localhost:3000/#/main, nothing is injected into the <ng-view>
Any advice would be greatly appreciated.

Having encountered this issue before I found a solution by telling express to serve files statically.
app.use(express.static('client'));
This tells express to send files from the 'client' directory as-is. This is used for files such as images, CSS & client side JavaScript. When referencing a file statically, paths are relative to the specified static directory so /client/views/main.html would be /views/main.html.
You can view the documentation for the express static middle ware here.

Related

how to use serve static file with express and react?

I have a project made with create-react-app and i would like to use it within express ( as i need some back end functionnality).
basically, my server render a blank page when i run it....
here is the code of my server:
const express = require('express');
const path = require('path');
const app = express();
// Serve the static files from the React app
app.use(express.static(path.join(__dirname, 'public')));
// An api endpoint that returns a short list of items
app.get('/api/getList', (req,res) => {
var list = ["item1", "item2", "item3"];
res.json(list);
console.log('Sent list of items');
});
// Handles any requests that don't match the ones above
app.get('*', (req,res) =>{
res.sendFile(path.join(__dirname , 'public', 'index.html'));
});
const port = process.env.PORT || 5000;
app.listen(port);
console.log('App is listening on port ' + port);
if i enter the endpoint http://localhost:5000/api/getList, i can see the result, but when i want to display my react app for the other end point, the page is blank.
The react app use different Route and i also added a proxy in the package.json.
my server source file is at the root of the react app like the image.
Does someone has an idea why the react app doesnt show?
Thanks
You have two lines that are kind of doing the same thing:
// Serve the static files from the React app
app.use(express.static(path.join(__dirname, 'public')));
Will serve your index.html file to http://localhost:5000/index.html
According to the Express documentation https://expressjs.com/en/starter/static-files.html
And then it seems like you have the second route:
app.get('*', is formatted incorrectly.
It would need to be app.get('/*'.
If you aren't directing the user to multiple routes then it might be better to just use the root, app.get('/', rather than trying to catch all routes.

Express JS static file with Angular $locationProvider.html5Mode (express.static)

I have a angular app using Express JS server side. I have removed the angular # (hashbangs) with the angular $locationProvider.html5Mode and set the base in the header of the html. Its all working fine until I reload the page when i'm not on the root. For instance if i am at http://myapp.com/anypath and reload my static files get the 'anypath' added in i.e. http://myapp.com/anypath/assets/css/app.css rather then http://myapp.com/assets/css/app.css
Here is my index.js my Express server is using
var express = require('express');
var app = express();
app.set('port', (process.env.PORT || 5000));
app.use(express.static(__dirname + '/app'));
app.all('/*', function(req, res, next) {
res.sendFile('index.html', { root: __dirname +'/app' });
});
app.listen(app.get('port'), function() {
console.log('Node app is running on port', app.get('port'));
});
I have looked at https://github.com/angular-ui/ui-router/wiki/Frequently-Asked-Questions#how-to-configure-your-server-to-work-with-html5mode and know this should answer my issue but im a noobs and cant get it to work :(
File Structure:
root >
index.js
node_modules
app >
assets >
css
images
bower_components
src >
js
views
I think its to do with the express.static but any help would be great!
Cheers
Just needed to check my css link more carefully, '/' was missing from the front.

Node Express server deep linking not working with AngularJS html5Mode

(Update: I solved the problem. Just look at the end of the question)
I am running with this problem that seems trivial to me, but I am very frustrated because I am not able to figure it out:
I scaffolded an Angular application using yeoman generator-angular. I need to use the html5mode of Angular to get rid of the hashtag (please, see app.js below). I am using a node express server (see server.js) to run the app built with grunt build.
As required, I added the option in the server to redirect to index.html when accessing the app from any specific route. It works with one level of "routing", i.e., localhost:8080/research, but it does not work for two "levels" or more, i.e., localhost:8080/research/human. In this case, when refreshing the browser, I get this error:
The stylesheet http://localhost:8080/research/styles/vendor.8089f103.css was not loaded because its MIME type, "text/html", is not "text/css". human
The stylesheet http://localhost:8080/research/styles/main.e7eff4cf.css was not loaded because its MIME type, "text/html", is not "text/css". human
SyntaxError: expected expression, got '<' vendor.01f538ae.js:1:0
SyntaxError: expected expression, got '<'
I have searched everywhere, I have tried all sort of options, but I am not able to fix it. I would really appreciate some help, please!
app.js
angular
.module('testAngularApp', [
'ngRoute',
'ngTouch',
'ngAnimate',
'ngSanitize',
'angulartics'
])
.config(function ($routeProvider, $locationProvider) {
$locationProvider.html5Mode(true);
$routeProvider
.when('/', {
templateUrl: 'views/mainFrontpage.html',
controller: 'MainFrontpageController'
})
.when('/research', {
templateUrl: 'views/research.html',
controller: 'ResearchController'
})
.when('/research/human', {
templateUrl: 'views/research-human.html',
controller: 'ResearchController'
})
.when('/research/fly', {
templateUrl: 'views/research-fly.html',
controller: 'ResearchController'
})
.otherwise ({
templateUrl: 'views/notyetready.html',
});
});
server.js
'use strict';
var express = require('express');
var path = require('path');
var morgan = require('morgan');
var fs = require('fs');
var currentDir = process.cwd();
var app = express();
var staticStats = fs.statSync( currentDir + '/dist');
if (staticStats.isDirectory()) {
app.use('/', express.static(currentDir + '/dist'));
// Here I have tried many different combinations
app.use("/styles", express.static(__dirname + "dist/styles"));
app.use("/scripts", express.static(__dirname + "dist/scripts"));
app.use("/views", express.static(__dirname + "dist/views"));
app.use("/fonts", express.static(__dirname + "dist/fonts"));
app.use("/templates", express.static(__dirname + "dist/templates"));
app.use("/images", express.static(__dirname + "dist/images"));
app.all('/*', function(req, res, next) {
// Just send the index.html for other files to support HTML5Mode
res.sendFile('dist/index.html', { root: __dirname });
});
var server = app.listen(8080);
console.log('Node Express server listening on http://%s:%d', server.address().address,8080);
}
else {
console.log('No /dist folder, did not start the server');
}
Update: Solution
Thanks to the comments of the users, I asked the question in a different way and found the solution that make it works here. That is, the <base href="/"> tag must be located before the <link rel="stylsheet"..> tags (what a hard time I got for such a stupid thing!)
Why not use nested routing in angular routing like this ?
https://github.com/angular-ui/ui-router
I wanted this to be just a comment but I can't yet, Have you tried placing the html5 mode below your routes ?
Can remove the if statement if you do not need it.
.when('/research/fly', {
templateUrl: 'views/research-fly.html',
controller: 'ResearchController'
})
.otherwise ({
templateUrl: 'views/notyetready.html',
});
if(window.history && window.history.pushState){
$locationProvider.html5Mode(true);
}
});
Maybe try using a different pattern to match against that sounds like the cause of the problem
app.all('/**/*', function(req, res, next)
However I would ask why are you serving the static files with node + express? If all you want is a static file server for local development why not try grunt-serve
Then if you want to serve the static files on a server you can use nginx which works really well with angular in html5 mode

Node / Angular app Uncaught SyntaxError: Unexpected token <

I'm following this node/angular tutorial and am getting the following errors:
I'm bootstrapping my app through node, which renders index page:
module.exports = function(app) {
app.get('*', function(req, res) {
res.sendfile('./public/index.html');
...
});
Which renders:
<html ng-app="DDE">
<head>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script>
<script src="bower_components/angular/angular.js"></script>
<script src="bower_components/angular-route/angular-route.js"></script>
<script src="js/app.js"></script>
<script src="js/controllers/main.js"></script>
</head>
<body>
This is the index page
<div ng-view></div>
I'd like Node to handle the initial page load, but Angular to handle the rest of the routing. The problem is here: It doesn't seem my angular routing is working. I put a self-exec fn run() in there to test, but it's not being called.
I'm simply trying to test display the testpage.html template:
app.js file:
angular
.module('DDE', [
'ngRoute'
])
.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/test', {
run : (function() {
alert('hit');
})(),
templateUrl: '../html/partials/testpage.html'
}).
otherwise({
redirectTo: '/test'
});
}
]);
The angular error isn't very helpful. I'm not sure what Unexpected token < means as I cannot find where I've added an extra < anywhere.
EDIT:
app.get('/', function(req, res) {
res.send('./public/index.html');
});
It should be able to find the stuff in bower components as the pathing is correct:
root/bower_components/angular/angular.js
root/bower_components/angular-route/angular-route.js
You are missing some settings in your app file on the server to handle all of the requests being made to the server. Here is a basic sample working express file, which you can modify to fit your environment:
var express = require('express');
var app = express();
app.use('/js', express.static(__dirname + '/js'));
app.use('/bower_components', express.static(__dirname + '/../bower_components'));
app.use('/css', express.static(__dirname + '/css'));
app.use('/partials', express.static(__dirname + '/partials'));
app.all('/*', function(req, res, next) {
// Just send the index.html for other files to support HTML5Mode
res.sendFile('index.html', { root: __dirname });
});
This file uses express.static to serve any content which is in the specific directory regardless of name or type. Also keep in mind that Express use statements are processed in order, and the first match is taken, any matches after the first are ignored. So in this example, if it isn't a file in the /js, /bower_components, /css, or /partials directory, the index.html will be returned.
I was able to resolve my issue with the unexpected token by moving my server.js file from the DIST directory into the directory above.
So my folder/file structure looks like this:
webroot - root folder
server.js
dist (folder)
browser (subfolder)
server (subfolder)

Issue Routing With Node.js - Cannot GET

I finally got everything working on a certain page, but the issue I'm facing now is when I create additional pages. I realize the issue must be with my routing, but I'm not sure how to change the server side code without effecting my app.
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
io.on('connection', function(socket){
// socket functions
});
http.listen(3000, function(){
console.log('listening on *:3000');
});
I would like to serve html in a folder 'public' and have files like index.html and other.html in there.
Configure your express app to use a static directory.
app.use(express.static('public'));
All files located under public can now be accessed. So a file called index.html can now be reached via /index.html
Further documentation can be found here:
http://expressjs.com/starter/static-files.html
If your folder is called public then you could do something like
app.use(express.static('./public'))
.get('/', function(req, res) {
res.sendFile('index.html', {root: 'public/'});
})

Categories