I have a server and client folder, inside my client folder I have 2 Angular apps /website and /dashboard
My current routing setup (just for development) going to / will load the website app and views and /dashboard loads the dashboard up:
//website api ==================================================================
var website = express.Router();
app.use('/', website);
app.use('/', express.static("../client/"));
console.log(__dirname + "../client/");
website.use(function(req, res, next) {
console.log(req.method, req.url);
next();
});
website.get('/', function(req, res) {
var path = 'index.html';
res.sendfile(path, { 'root': '../client/website/' });
});
//dashboard api ================================================================
var dashboard = express.Router();
app.use('/dashboard', dashboard);
dashboard.use(function(req, res, next) {
console.log(req.method, req.url);
next();
});
dashboard.get('/dashboard', function(req, res) {
var path = 'index.html';
res.sendfile(path, { 'root': '../client/dashboard/' });
});
// API to add new accounts:
app.post('/api/accounts/', accountsController.create);
In my dashboard app, the accounts controller I have the following $resource call:
var Account = $resource('/api/accounts');
Which is suppose to hit this API on my server main.js:
// API to add new accounts:
app.post('/api/accounts/', accountsController.create);
However currently getting a 404 on the call
'POST http://localhost:9999/api/accounts 404 (Not Found)'
I think it's the mismatch of trailing slash vs. no trailing slash between your angularjs code and your expressjs code. Try app.post('/api/accounts', accountsController.create);.
Related
Okay so this question originates from this post, which is also my question but sorta moved onto this problem.
Now the problem is, my angular app works but when it comes to Node routes, like /login, the browser thinks it's an Angular route. The browser does detect it as a Node route when I refresh the whole page but not when I am navigating the site once Angular routing has kicked in.
Long story short, here are my route files:
require('./routes/routes.js')(express, app);
require('./routes/default.js')(express, app);
routes.js file:
module.exports = function(express, app){
var router = express.Router();
router.get('/', function(req, res){
res.render('index');
});
router.get('/login', function(req, res){
if (req.isAuthenticated()){
res.render('index');
} else {
res.render('login');
}
});
default.js:
module.exports = function(express, app, passport, Promise){
var defaultRouter = express.Router();
defaultRouter.get('/*', function(req, res, next) {
res.render('./views/index.html');
});
};
Your help will be very much appreciated.
Thanks
I gave up on making this work on the root URL so I added /index to the baseURL like this:
index.html file:
<head>
<base href="/index/">
</head>
The, I added a catch all to the routes.js file, as below:
module.exports = function(express, app){
var router = express.Router();
router.get('*', function(req, res, next) {
if(req.url == '/' || req.url == '/login'){
next();
} else {
res.sendfile('./views/index.html');
}
});
router.get('/', function(req, res){
res.render('index');
});
router.get('/login', function(req, res){
if (req.isAuthenticated()){
res.render('index');
} else {
res.render('login');
}
});
With the angular file of course having this:
$locationProvider.html5Mode({
enabled: true,
requireBase: true
}).hashPrefix('');
And there. It works like a charm now.
I hope this helps whoever are in my shoes.
I created a project on Node.js + AngularJS I have routes in this project. How I can create redirect to '/' if the user prints whatever link in searching panel.
i would recommend to use ExpressJS as nodeJS framework but via nodeJS you can use the router library to acheive the same.
var finalhandler = require('finalhandler')
var http = require('http')
var Router = require('router')
var router = Router();
//other route urls here
//have this at the end
router.get('/*', function (req, res) {
res.setHeader('Content-Type', 'text/plain; charset=utf-8')
res.end('Hello World!');
//or write you logic here.
})
var server = http.createServer(function(req, res) {
router(req, res, finalhandler(req, res))
})
server.listen(3000)
Read in detail about the Router Library
Also read here
I have a single page app written in AngularJS and NodeJS. On the client side, there are several paths that the user can navigate to:
http://jabaridash.com/#!/home
http://jabaridash.com/#!/interests/travel
When the user types in a path that does not exist such as http://jabaridash.com/#!/foo, AngularJS handles it by rerouting to the /notFound path, and then that page redirects the user back to the home page. This is the code:
$urlRouterProvider.otherwise('/notFound');
This works when the path begins with #!/anyPath. However, if I were to type jabaridash.com/whatever, Angular does not reroute it. I am not sure if that has to do with the fact that I am using $stateProvider and modules to navigate, or I need to handle that type of path on the backend. I am assuming that I need to handle it on the Node side, because I do have one REST endpoint called photography setup on the NodeJS side, which can be accessed via jabaridash.com/photography (without #!). This endpoint works fine, but any other endpoint that I do not have setup will get a response of:
Cannot GET /something
This is to be expected, as there is no endpoint there. So essentially, how do i get NodeJS to redirect to my index.html. The way that I am serving the static page follows:
/**
* #description Set up the server
*
* #param dir directory to serve the index.html from
*/
function setupServer(dir) {
server.use(express.static(dir), function(req, res, next) {
// Allow cross origin from any host
res.setHeader('Access-Control-Allow-Origin', '*');
next();
});
// Set up the photography REST endpoint
photography_controller(server, dir);
}
My photography endpoint is setup as follows:
server.get('/photography', function(req, res) {
var searchPath = '/client/modules/interests/photography/img/thumbnail/';
// Send the list of files for use on client side
res.send(fileList(dir + searchPath, searchPath));
});
Is there a generic way to tell Node to say..."If the endpoint / HTTP method is not defined for a given path, redirect to a known path?"
This snippet below tells express to redirect to not-found when the path start with /example but has no specified handler in the router. Other routes that don't start with /example will not redirect because they won't be routed into the router in the first place.
const express = require('express');
const app = express();
// create a router for /example
var router = express.Router()
.get('/', function (req, res) {
res.send('example home');
})
.post('/about', function (req, res) {
res.send('About example');
})
/* catch all middleware for routes starting
with /example that redirects to /not-found */
.use(function (req, res, next) {
return res.redirect('/not-found');
});
// attach router
app.use('/example', router);
// create a not-found router handler
app.get('/not-found', function (req, res) {
res.send('Not found page');
});
app.listen(3000, () => console.log('App listening on port 3000'));
Right after your routes definition, do the following:
server.get('/photography', function(req, res) {
//do something
});
// catch 404 and forward to error handler
server.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
//
// error handler
server.use(function(err, req, res, next) {
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
//render the page you want to navigate to. In this example, I navigate the user to google
res.redirect('http://google.com');
});
I am trying to setup a base for a MEAN application. I created the new project using Angular CLI, added Express.js, MongoDB modules to the application. In the app.js file I have the following configuration:
var express = require('express');
var bodyParser = require('body-parser');
var session = require('express-session');
var path = require("path")
var app = express();
var conf = require('./config/conf');
var server = require('http').Server(app);
var mongoDB = require('./adapters/mongodb')
var mongoClient = new mongoDB(conf);
app.use(bodyParser());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'dist/index.html'));
});
app.use(function (req, res, next) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type,__setXHR_');
res.setHeader('Access-Control-Allow-Credentials', true);
next();
});
mongoClient.connect(function (dbconn) {
app.dbconn = dbconn;
app.conf = conf;
console.log("************************************************************");
console.log(new Date() + ' | CRUD Server Listening on ' + conf['web']['port']);
console.log("************************************************************");
server.listen(conf['web']['port']);
var Routes = require('./routes/http-routes');
new Routes(app);
});
I setup a hello world route for now and no changes done to the angular sources, which means I would land at the Angular default starting page. But I cant land at the page but instead a white screen page. However, I can access the routes using Postman. I do ng build and then node app.js to run the application. What am I doing wrong?
You should use the Express way to handle routes
First
const router=express.Router();
Then let's suppose you have a file using only authentication routes
const authentication = require('./routes/authentication')(router);
To conclude, you only have to do :
app.use('/authentication', authentication);
This allows a better divison of your routes
You 'll use your routes this way
module.exports= (router)=>{
router.get('/',(req,res)=>{
res.json(message:'Hello World');
});
return router;
To set angular routes you need the router module, for more details read the documentation
You serve only index.html from your Angular App. But you need also serve assets, css and javascript. Easiest would be something like this (but you need to adjust directory names:
app.use('/js', express.static(path.resolve(__dirname, 'dist/js')));
app.use('/css', express.static(path.resolve(__dirname, 'dist/css')));
app.use('/assets', express.static(path.resolve(__dirname, 'dist/assets')));
I have an angular application in which when I used
$locationProvider.html5Mode(true);
for removing #! , it works good. but when I refreshes the page it gives error that
Get GET /c/electronic/computer/laptop not found which is my url
This is my app.js page
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var index = require('./routes/index');
var app = express();
app.use(function(req,res,next){
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
res.setHeader('Access-Control-Allow-Credentials', true);
next();
});
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', index);
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
app.use(function(err, req, res, next) {
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
This is my index page I putted all my functions and apis for firing queries where in models there had my mongodb's queries
var express = require('express');
var router = express.Router();
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
Category = require('./models/category');
Product = require('./models/product');
http = require('http');
mongoose.connect('mongodb://localhost/baazaronline');
var db = mongoose.connection;
router.get('/api/category', function(req, res){
Category.getCategory(function(err, category){
if(err){
throw err;
}
res.json(category);
});
});
router.get('/api/product', function(req, res){
Product.getProduct(function(err, product) {
if(err){
throw err
}
res.json(product);
})
});
router.get('/api/product/:_id', function(req, res){
Product.getProductById(req.params._id, function(err, product){
if(err){
throw err;
}
res.json(product);
});
});
Kasun, the reason that this is occurring is because you are trying to refresh the page from one of your sub routes (has nothing to do with ui-router).
Basically if you request www.yourdomain.com/ you likely have your server setup to return index.html which bootstraps your angular app. Once the app has loaded, any further url changes take html5Mode into consideration and update your page via ui-router.
When you reload your page the angular app is no longer valid as it has not loaded yet, so if you are trying to load a sub route (for example: www.yourdomain.com/someotherpage), then your server does not know how to deal with /someotherpage and likely returns 404 or some other error.
What you need to do is configure your server to return your angular app for all routes. I primarily use node/express, so I do something like:
app.get('*', function(req, res, next) {
// call all routes and return the index.html file here
}
Note: I usually use something like this as a final catch all, however I also include other routes above it for things like requesting static files, web crawlers, and any other specific routes that need to be handled.