(NodeJS 9.4 and Angular 5).
// In app.js I have,
app.use('/', login);
app.use('/app', application);
// in the route file application.js, I have,
router.get('/', function(req, res, next) {
res.render("application/index");
});
// in angular 5 I have
{
path : 'angular_path',
component : AngularComponent
},{
path : '**',
redirectTo: 'angular_path'
}
Now when I enter the URL
localhost:3000/app
it takes me to
localhost:3000/#/angular_path
All these are working perfectly fine for me,
but now when I refresh the page, it sends me back to the login page,
That's why I need the URL to be
localhost:3000/app/#/angular_path
I need the word /app/ before the angular route.
||HELP||
try this code to set prefix in the URL.
Add this code in the app.js
var router = express.Router();
app.use('/app', router);
Related
first of all it's working proper in my local but it works the way i don't want on heroku.
I working on a MERN stack app and I have express path same time react router path.
https://test.herokuapp.com/project
in my node.js express side
server.js
--------
/* Router */
import routes from "./routes/index.js"
app.use('/', routes)
/* For Deployment */
if(process.env.NODE_ENV === "production") {
app.use(express.static(path.join(__dirname, './../client/build')))
app.get('*', (req, res) => {
res.sendFile(path.resolve(__dirname, "../client/build/index.html"));
})
}
routes/index.js (it returns project data from mongodb)
---------------
router.get( '/project', ProjectController.getAll);
at the same time i have a another route in my react side
const routers = (isUserAuth, isAdminAuth) => [
{
path: '/project',
exact: true,
element: <Project />
}
]
http://localhost:3000/project
that route when react router redirect with a NavLink working and if page refresh manually still working in my local. But when it comes to heroku platform it's working redirect with NavLink but it doesn't work when refresh the page. When refresh the page as i said it returns project data from express serve nodejs side.
I think it's about the first code block I put above. thanks..
How do I prevent Angular routing from interferring with routes from an Express Node Server?
I'm setting up some routes ( to node-RED middleware) in my Express server:
server.js
// Serve the editor UI from /red
app.use(settings.httpAdminRoot,RED.httpAdmin);
// Serve the http nodes UI from /api
app.use(settings.httpNodeRoot,RED.httpNode);
// Angular DIST output folder
app.use(express.static(path.join(__dirname, 'dist')));
// Send all other requests to the Angular app
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'dist/index.js'));
});
but in my router module they get always overridden ( with our without the default path redirection)
routing.module.ts
const appRoutes: Routes = [
{
path: "example-page",
loadChildren: "../modules/example/example.module#ExampleModule?sync=true"
},
// Last routing path specifies default path for application entry
/* {
path: "**",
redirectTo: "/example-page",
pathMatch: "full"
},*/
];
I'm only providing this little code because I want to ask in general how do I prevent Angular from interferring with routes defined in an Express server and what is the best practice for routing in an Express/ Node.js + Angular + AspNetCore + Webpack app.
If you're using Angular, then let Angular handle all pages. This code takes care of that and hence angular is handling all routes.
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'dist/index.js'));
});
If you want express to handle some routes instead of angular, handle that route before handling angular route as follows:
app.get('/some-non-angular-path', (req, res) => {
//code to handle this path. once it is handled here, angular won't be involved
//non-angular-paths should come first in the order
});
app.get((req, res) => {
res.sendFile(path.join(__dirname, 'dist/index.js'));
});
I have a server.js file where I require my routing file as below..
userRouter = require('./controllers/user.js');
In the server.js file I have routing for home as..
server.get('/', function(req, res){
res.render('home');
});
The home.ejs is put into the layout.ejs body and displays fine. The problem I am having is with the users/new route in the controllers folder..
router.get('/new', function(req, res){
res.render('users/new')
});
router.post('/', function(req, res){
var newUser = User(req.body.user);
})
The code above isnt being injected into the body of the layout.ejs. If I type in the route http://localhost:3000/users/new it works, but its not in the layout.ejs body. How can I fix this?
Also, how can I get my links in the web app to redirect to the correct route; i.e, signup link goes to http://localhost:3000/users/new
I am building my first application using NodeJS & ExpressJS for the backend and AngularJS front end. I have all my front end routes working how I want, but I cannot figure out how to properly configure the Node backend so that when a specific URL is entered into the address bar, Node renders only the same Angular app every time.
For example, if I use About as a link to my about page in Angular, then the correct view will render and the address bar will show localhost:8080/about. However, if I just manually type in localhost:8080/about then Node responds with Cannot GET /about. Now I understand this is because my backend currently only handles the following:
var express = require('express');
var crypto = require('crypto');
var app = express();
app.set('views', __dirname + '/public');
app.engine('html', require('ejs').renderFile);
app.use(express.static(__dirname + '/public'));
app.get('/', function(req, res){
res.render('index.html');
});
// API
app.get('/api/sync', function(req, res){
// Here we generate a 32 byte string and make it the key
var num = Math.floor(Math.random()*100);
var key = crypto.createHash('md5').update(num.toString()).digest('hex');
key = key.slice(0, key.length/2);
console.log('Created key: ' + key);
res.send(key);
});
var server = app.listen(8080, function(){
console.log('Listening on port %d', server.address().port);
});
So what I want to do is make it so EVERY request to Node renders the same index.html page but then properly routes the view in Angular based on the URL. What is the best way to do this?
I just realized that using:
app.get('*', function(req, res){
res.render('index.html');
});
And placing this after all other routes I want to catch first will work.
Since I don't have enough reputation yet to just add a comment, it's worth noting that res.render() won't work if you're not using a server-side template rendering engine (as you are using EJS). You would instead want to use something like res.sendFile() if you were just serving a static HTML and Angular page with all the routing set up in Angular.
app.get( '*', function( req, res ) {
res.sendFile( __dirname + '/public/index.html' );
} );
The best way handle angular route in angular-app and backend route in backend.
Angular/Frontend:
sampleApp.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/', {
templateUrl: 'templates/home.html',
controller: 'MainController'
}).
when('/about', {
templateUrl: 'templates/about.html',
controller: 'AboutController'
}).
// >>> redirect other routes to
otherwise({
redirectTo: '/'
});
}]);
Backend:
For render static html you don't need app.get(...)
simple place index.html into:
public/index.html
and express serve it as html. Other not exists pages(routes) return 404 error and it is right.
In this case API fully separate and independent and angular fully single page app. Express serve static resources needed for angular.
I am building an app with express js which will have different clients like web and mobile. I didnt want to use one app for both as some middleware would be additional burden. For say like session middleware. So is it possible for one project to have two apps. And how would it work?
The app object that you make in express is a function(req,res,next) that is suitable for Express's own middleware chains. So you can use app.use to send requests matching a leading path fragment to an app defined elsewhere.
Docs: http://expressjs.com/api.html#app.use
$ npm install express
//mobile.js
var app = require('express')();
app.get('/', function(req, res){
res.send('Mobile Route')
});
module.exports = app;
//desktopApp.js
var http = require('http');
var express = require('express');
var desktopApp = express();
var mobileApp = require('./mobile.js');
desktopApp.use('/mobile', mobileApp)
desktopApp.use(desktopApp.router);
desktopApp.use(express.errorHandler());
desktopApp.get('/', function(req, res){
res.send('Desktop Route')
});
desktopApp.get('/mobile', function(req, res){
// Because Express respects the order that you set up the middleware chain,
// the mobileApp `/mobile` route gets first dibs to send a response or next()
res.send('Inaccessible Desktop Route')
});
desktopApp.get('/mobile/foobar', function(req, res){
// When mobileApp can't find any suitable route matching this path, it gives
// up, and desktopApp continues to pass the request down the middleware stack.
// It ends up matching this route, where we send a response
res.send('Desktop Route')
});
http.createServer(desktopApp).listen(3000, function(){
console.log('Listening on 3000');
});
// Results
$ curl localhost:3000/
Desktop Route
$ curl localhost:3000/mobile/
Mobile Route
See the vhost example on the express github repository.
You can have a "main" app, which routes the requests to one app or another. You should write a middleware to establish the conditions where one app or another are requested. express.vhost is a good example, but maybe you need other checks than the domain one.
main-app.js
(The file called to start the server.)
// load dependencies
var main = express();
main.use( express.vhost( 'mobile', require( './the-mobile-app' ) );
main.use( express.vhost( '*', require( './the-web-app' ) );
main.listen( /*...*/ )
the-mobile-app and the-web-app.js
var app = express();
//
// setup your application conf, middleware, and routes
//
module.exports = app;
I wanted to share a different approach that I used in a project recently:
function renderAppropriate(template1, template2){
return function(req, res){
if(req.session && req.session.mobileOn){
res.render(template1);
} else {
res.render(template2);
}
};
};
app.get('/', function(req, res, next){
// do some stuff
next()
}, renderAppropriate('someMobileTemplate', 'someDesktopTemplate')
);