Express + Angular routing bug - angularjs

I am working on learning authentication using Angular 1 and Express. I've got my backend set up for testing purposes, and i'm now working on the front end. I've got basic routes set up.
This is the core to my front end:
function router($stateProvider, $urlRouterProvider, $locationProvider) {
$urlRouterProvider.otherwise('/');
$stateProvider
.state('home', {
url: '/',
templateUrl: 'views/home/',
controller: 'mainController'
})
.state('login', {
url: '/login',
templateUrl: 'views/login/',
controller: 'loginController'
});
$locationProvider.html5Mode(true);
}
And here are the routes on the back end that would be relevant:
app.use(express.static(path.join(__dirname, 'public')));
app.get('/', function(req,res){
res.sendFile(path.join(__dirname, 'public/', 'index.html'));
});
The only other routing I have is for my API, which use the constant apiRouter and inject /api/ into those routes.
Now, the issue comes when I try to access a route directly from the browser. I've I nagivate to localhost:8080/login I get the error Cannot GET /login, but using a ui-sref on my index page, it seems to work just fine.
Any ideas?

So I figured out what my issue was.
After my root path GET statement in my server file, I need to add the following code:
app.get('*', function(req,res){
res.sendFile(path.join(__dirname, 'public/', 'index.html'));
});
What was happening, is that Express was trying to find a /login route that I had defined. The problem is, that route needs to be handled by Angular, and not Express, so the '*' is a catch-all for any route that Express doesn't know how to explicitly handle, it then hands off that responsibility to the index.html file.

Related

File serving using ngRoute in Angular with NodeJS server

I am trying to run AngularJS, using Angular Router, with a NodeJS server. I do not plan on serving the various views in Node, but instead I want to use the angular router. This first page is served correctly with no errors but when I try to click on another link, the browser displays the following
error code. Below is the relevant code from the server script, the routing script, and where the link in the HTML is.
HTML Link
<li>Add Workout</li>
Server.js
app.get('/', function(req, res) {
res.sendFile(path.join(__dirname + '/public/app/views/home.html'));
});
app.use(express.static('public'));
App.js
var app = angular.module("fitness2Uapp", ["ngRoute"]);
app.config(function($routeProvider) {
$routeProvider
.when("/", {
templateUrl : "./app/views/home.html"
})
.when("/browse", {
templateUrl : "./app/views/browse.html"
})
.when("/add", {
templateUrl : "./add.html"
})
.when("/workout", {
templateUrl : "./app/views/workout.html"
});
});
Try putting in a "catch all" route that just redirects back to the main page. This will in turn allow the angular routing mechanism to kick in. Right now the problem is that it's trying to find an endpoint path of '/add' on the node server, but nothing is found. This should be the very last route established on your server.
I personally use AngularJS and had to do this, and everything works great. Not sure if this will also perform the same way as Angular2+
// Catch all if all other routes fail to match.
app.get('*', (req, res) => {
res.sendFile(path.resolve(`${__dirname}/path/to/home.html`));
});

Can we use client-side angularjs routing using ui router with expressjs server side routing in nodejs. Below is the example

Example:
var bodyparser=require('body-parser');
var fs=require('fs');
var express=require("express");
var myApp = express();
var MongoClient=require('mongodb').MongoClient;
var assert=require('assert');
var url = 'mongodb://localhost:27017/dbname';
var ObjectId=MongoClient.ObjectID;
var http=require('http');
myApp.use(express.static("."));
myApp.use(bodyparser.json());
myApp.listen(5000);
I am using server(apache or node) to load only index file from there after am using ui-router to make it a SPA which is working well wen run in apache server but this is not working wen ran on node:
the index is being loaded correctly but following url :
http://localhost:5000/Test/#/dashboard
throws the message : "Cannot GET /Test/" in node server, How to make the Routing to work correctly in expressjs
$urlRouterProvider.otherwise('/login');
var DASHBOARD_ROOT = 'templates';
$stateProvider.state('index', {
url: '/login',
templateUrl: 'login.html',
controller: 'employeeInfoCtrl'
});
$stateProvider.state('dashboard', {
abstract :true,
url: '/dashboard',
templateUrl: 'dashboard.html',
controller: 'employeeInfoCtrl'
});
$stateProvider.state('dashboard.home',{
url:'',
templateUrl: DASHBOARD_ROOT +'/Home.html'
});
$stateProvider.state('dashboard.about',{
url:'/about',
templateUrl: DASHBOARD_ROOT +'/about.html'
});
$stateProvider.state('dashboard.employeeinfo',{
url:'/employeeinfo',
templateUrl:DASHBOARD_ROOT+'/employeeinfo.html'
});
In node : you have to add path GET#test
myApp.get('/test',function(req,resp){
resp.render('index.html');
})
you can achieve that by targeting your client build directory with
app.use(express.static('dist')) //dist is where your js is bundled
then redirect all the requests using wildcard (*) to your index.html file
app.get('*', (req, res) => res.sendFile('index.html')));

Routing working locally, not on Heroku servers

My AngularJS application won't route to /login when accessing /login directly. It will route to /login if I first access / then route from / to /login.
It is working on my local environment but not with Heroku servers. Are there some settings I have to configure on the Heroku server?
I am using angular-ui-router to route to different states throughout my application.
My app.js config snippet looks like this:
angular.module('app', [
angularUiRouter
])
.config(($stateProvider) => {
"ngInject";
$stateProvider
.state("home", {
url: "/",
template: "<home></home>"
})
.state("login", {
url: "/login",
template: "<login></login>"
});
})
Answering my own question.
Since the setup on this application is using MEAN stack, we have to also add routing from server side to client.
For all templates in AngularJS there has to be a routing from Express to AngularJS to index.html
for all templates and routings created in angular we need to get the request and send index.html in response
when we use angularjs stateProvider to route in Angularjs.., we have to also add routing to /dist/index.html from server side.
$locationProvider.html5Mode(true).hashPrefix('!'); has to be defined in app.js on AngularJS side
A snippet of my Server.js file:
var express = require('express');
var app = express();
app.use(express.static(__dirname + '/dist'));
app.get('/', function(req, res){
res.sendFile(__dirname + '/dist/index.html');
});
app.get('/login', function(req, res){
res.sendFile(__dirname + '/dist/index.html');
});

Angular URL routing issue

So I needed to change my URL so that google analytics could track it. Google analytics wouldn't accept it with the "/#/" (hash) in the link. That said, I used Angular's locationProvider and revised my app routing with:
(function() {
'use strict';
angular
.module('mbapp')
.config(routerConfig);
/** #ngInject */
function routerConfig($stateProvider, $urlRouterProvider, $locationProvider) {
$stateProvider
.state('home', {
url: '/',
templateUrl: 'app/main/main.html',
controller: 'MainController',
controllerAs: 'main'
});
$stateProvider
.state('steps', {
url: '/steps',
templateUrl: 'app/steps/steps.html',
controller: 'StepsController',
controllerAs: 'steps'
});
// use the HTML5 History API
$locationProvider.html5Mode(true);
$urlRouterProvider.otherwise('/');
}
})();
My URL is fine and changes it to http://website.com/steps rather than http://website.com/#/steps. However, now, if a user refreshes (f5) the link it then throw a 404 error and not sure why. Additionally, it seems that somehow this gets injected as the URL when the refresh is called "http://website/steps#/steps".
Any ideas on this?
Thanks much.
The problem is probably on the server side. You have to configure your server so it responds to every request with your html file. For example in express:
var app = require('express')();
app.configure(function(){
// static - all our js, css, images, etc go into the assets path
app.use('/assets', express.static('/assets'));
app.get('/api/users/:id', function(req, res){
// return data for user....
});
// This route deals enables HTML5Mode by forwarding missing files to the index.html
app.all('/*', function(req, res) {
res.sendfile('index.html');
});
});
When you reload the page, the request goes to the server side of your application, and it tries to resolve the url but it probably can't, because those routes only exists on the client side of your application.
Also it is a good idea to prefix every server side route with an /api route prefix, so you can easily distinguish between client side and server side routes.

AngularJs routing, multiple requests in server

I want to use angularjs routing, I'm using but it's making extra requests in server side. Anyone know the solution of this problem, or I'm doing something wrong?
Client app.js
app.config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
$locationProvider.html5Mode({enabled: true, requireBase: false})
$routeProvider.
when('/', {
templateUrl: '/tpl/main.tmp.html',
controller: 'MainCtrl'
})
.otherwise({redirectTo: '/'})
}])
//routes.js
app.get('/', function(req, res) {
console.log("test")
res.render(__dirname+'/public/tpl/index.html', siteConfig)
})
//output
//test
//test
//test
//test
Files:
models
public
|-css
|-js
|--app.js
|--angular.js
app.js
A few things may cause this, a closer inspection of both request packets might narrow down the cause. Some ideas to check for:
The browser keeps trying to fetch the site favicon because it can't find one
Fetching an image with a # in the URL (i.e. <img src="#"/>)
Meta refresh tag in the HTML
Web browsers may retry requests when the connection is closed before receiving a response

Resources