HTTP ERROR 404 after page refresh in ANgular JS1 - angularjs

I am using http-server package to run my angular js project. My directory structure is below:-
angulardemo/app/public/controller
angulardemo/app/public/app.js
angulardemo/app/public/index.html
angulardemo/app/public/view
ang my app.js file is
var app = angular.module('angulardemo', ['ngRoute', 'ngCookies'])
.constant('API_URL', 'http://127.0.0.1:8001')
.config(function ($routeProvider, $locationProvider, $httpProvider) {
$httpProvider.defaults.headers.common = {'Content-Type' : 'application/json'};
$httpProvider.defaults.headers.post = {};
$httpProvider.defaults.headers.put = {};
$httpProvider.defaults.headers.patch = {};
/**
*
* Checks for url access
*/
resolver = function (access){
return {
load: function($q, AuthService, $location){
if(access){
return true
}else{
if(AuthService.checkLogin()){
return true;
}
else{
$location.path("/login");
}
}
}
}
}
$routeProvider
.when('/', {
templateUrl : "/view/home.html",
controller : 'PagesController'
})
.when('/home', {
templateUrl : "/view/home.html",
controller : 'PagesController'
})
.when('/about', {
templateUrl : "/view/about.html",
controller : 'PagesController'
})
.when('/team', {
templateUrl : "/view/team.html",
controller : 'PagesController'
})
.when('/work', {
templateUrl : "/view/work.html",
controller : 'PagesController'
})
.when('/price', {
templateUrl : "/view/price.html",
controller : 'PagesController'
})
.when('/users/:user_type', {
templateUrl : "/view/developers.html",
controller : 'UsersController'
})
.when('/user/show/:id', {
templateUrl : "/view/user.details.html",
controller : 'UsersController'
})
.when('/contact', {
templateUrl : "/view/contact.html",
controller : 'PagesController'
})
.when('/register', {
controller: 'AuthController',
templateUrl: '/view/auth/register.html',
resolve:{
loggedIn: function(AuthService, $location){
if(!AuthService.checkLogin())
return true;
else
$location.path("/home");
}
}
})
.when('/login', {
controller: 'AuthController',
templateUrl: '/view/auth/login.html',
resolve:{
loggedIn: function(AuthService, $location){
if(!AuthService.checkLogin())
return true;
else
$location.path("/home");
}
}
})
.when('/dashboard', {
controller: 'DashboardController',
templateUrl: '/view/dashboard/index.html',
pageTitle: 'dashboard',
resolve:resolver(false)
})
.when('/users_personal/:id', {
controller: 'UsersController',
templateUrl: '/view/users/personal.html',
pageTitle: 'personal_details',
resolve:resolver(false)
})
.when('/users_edu/:id', {
controller: 'UsersController',
templateUrl: '/view/users/edu.html',
pageTitle: 'edu_details',
resolve:resolver(false)
})
.when('/users_contact/:id', {
controller: 'UsersController',
templateUrl: '/view/users/contact.html',
pageTitle: 'contact_details',
resolve:resolver(false)
})
.when('/users_other/:id', {
controller: 'UsersController',
templateUrl: '/view/users/other.html',
pageTitle: 'other',
resolve:resolver(false)
})
.when('/logout', {
resolve : {
logout: function ($routeParams, $location, $http, API_URL){
$http.get(API_URL + "/api/auth/logout").success(function (response) {
if(response === "OK"){
localStorage.removeItem('auth');
$location.path('/login').replace();
}
})
}
}
})
.otherwise({
redirectTo: '/',
});
$locationProvider.html5Mode({
enabled: true,
requireBase: false
}).hashPrefix('*');
}).run(['$http', '$cookies', function($http, $cookies) {
$http.defaults.headers.post['X-CSRFToken'] = $cookies.csrftoken;
}]);
when I am running project using "http-server" with in the app directory command I got url as http://127.0.0.1:8080
http://192.168.10.137:8080
all the pages are working fine but when I am refreshing the page I am getting This 127.0.0.1 page can’t be found
No web page was found for the web address: http://127.0.0.1:8080/team
HTTP ERROR 404
So can anyone please tell that what wrong thing is here. and provide the solution.
See the directory structure in git hub:-
https://github.com/sanjaysamant/angulardemo/tree/local/app
Angular js files are in the public directory
Thanks
Please see terminal screen shot:

Whenever you are on a sub-URL such as /team and you refresh the page, the Node-Server looks for a HTML-File that is in the folder team on your server, which is not what you want. You need the server to redirect all those URL's to your index.html so that it loads the Angular Application, which can then properly initialize the correct page.
You can try the following in your server.js file:
//routes
app.use('/api/auth', require('./controllers/auth/auth.controller'));
app.use('/api/users', require('./controllers/users/users.controller'));
app.use('/api/user/', require('./controllers/users/users.controller'));
// Redirect unmatched routes (All specific routes such as /api/* need to be before this call)
app.use(redirectUnmatched);
function redirectUnmatched(req, res) {
res.redirect("/");
}

What #Chnoch suggested is correct, however I want to give you a different approach.
app.get('*', function(req, res)
{
res.send('/path/to/index.html');
});
Because all requests for a page will be a GET requests, you don't need to specify POST, and with this approach it will preserve the current URL you are on (eg. if you were on http://127.0.0.1:8080/team you will refresh and still be on /team), wheras #Chnoch's approach will always redirect you back to http://127.0.0.1:8080/.
What this will do is for any request that can't be resolved by the Node server, it will just render plain index page that can then be handled by Angular's ngRoute to display templates (you can also use templating engines like EJS or Pug with this, just replace the res.send with the rendering function).
Just make sure that the above code is after ALL other routes you want to be resolved by the Node server (eg. your API etc.) so it doesn't interfere with routes after it, since this is a catch all route.

Related

AngularJs redirect to route not working properly

I am trying to redirect to another route after an event, but it shows only url change (http://localhost:8000/login changed to http://localhost:8000/login#/home). I want to change it to http://localhost:8000/home#, but I can not figure out how to do that. And my route for this url not working.
app.js:
var app = angular.module('laravel', ['ngRoute'])
.constant('API_URL', 'http://localhost:8000/')
.config(function ($routeProvider, $locationProvider) {
$routeProvider
.when('/login', {
controller: 'authController',
templateUrl: 'resources/views/auth/login.blade.php',
})
.when('/home', {
templateUrl : "resources/views/home.bade.php",
controller : 'homeController'
})
.otherwise({
redirectTo: '/',
});
});
auth.js, containing my authController:
app.controller('authController', function ( $scope, $http, $location, API_URL){
$scope.login = function(){
var url = API_URL + "login";
$http.post(url, $scope.file).success(function (response) {
console.log("coming in homepage!!");
// sessionStorage.setItem('user', $scope.user);
$location.path('/home');
});
}
});
The above code just converts the URL http://localhost:8000/login to http://localhost:8000/login#/home.
You need something like this i guess
$location.path('/home').replace();
You can check API doc for $location.
I got it.
If you configure $location to use html5Mode (history.pushState), you need to specify the base URL for the application with a tag or configure $locationProvider to not require a base tag by passing a definition object with requireBase:false to $locationProvider.html5Mode():
$locationProvider.html5Mode({ enabled: true, requireBase: false});
//$locationProvider.html5Mode(true); //if we want to remove html5mode requirebase.

Secret link routing with AngularJS

The concept is this:
When the administrator logs in successfully (from admin.html) he is redirected to a page called adminMenu.html. Now since I need to put the adminMenu.html in the routing, users may obviously access this page from the address bar.
app.controller('adminCtrl', function($scope, $http, $location) {
$scope.chkCredentials = function(information) {
$http.post('php/getLogin.php', information).success(function(data) {
if (data == true) {
alert("Logged in.");
$location.path("/adminMenu"); //go to admin page
} else {
alert("Incorrect Credentials!");
}
});
}
});
How do I make it such that the page is "available for access", when the data is true from the above code?
This is my routing just in case needed.
var app = angular.module("app", ["ngRoute"]);
app.config(function($routeProvider) {
$routeProvider
.when("/home", {
templateUrl : "home.html"
})
.when("/proverbs", {
templateUrl : "proverbs.html"
})
.when("/comments", {
templateUrl : "comments.html"
})
.when("/admin", {
templateUrl: "admin.html"
})
.otherwise({
redirectTo:"/home"
})
});
Thanks and my apologies since I'm new for this.

How to restrict the page from redirect after login/ logout in Angularjs?

I need to restrict the user from redirect and need to login only with authentication.
I tried but I can redirect to login page using back button and again come to same page using forward button. Even I can go to the required page using URL without login.
My code :
config.$inject = ['$routeProvider', '$locationProvider'];
function config($routeProvider, $locationProvider ) {
$routeProvider
.when('/login', {
controller: 'LoginController',
templateUrl: 'view/login.view.html',
controllerAs: 'vm'
})
.when('/profileData', {
controller: 'profileDataController',
templateUrl: 'view/profiledata.view.html',
controllerAs :'vm'
})
.when('/questionBank', {
controller: 'questionbankController',
templateUrl: 'view/questionbank.view.html',
controllerAs: 'vm'
})
.when('/dashboard', {
// controller: 'PersonalInfoController',
templateUrl: 'view/dashboard.view.html',
controllerAs:'vm'
})
.otherwise({ redirectTo: '/login' });
}
run.$inject = ['$rootScope', '$location', '$cookieStore', '$http'];
function run($rootScope, $location, $cookieStore, $http) {
// keep user logged in after page refresh
$rootScope.globals = $cookieStore.get('globals') || {};
if ($rootScope.globals.currentUser) {
$http.defaults.headers.common['Authorization'] = 'Basic ' + $rootScope.globals.currentUser.authdata; // jshint ignore:line
}
$rootScope.$on('$locationChangeStart', function (event, next, current) {
//redirect to login page if not logged in and trying to access a restricted page
var restrictedPage = $.inArray($location.path(), ['/dashboard','/questionBank', '/profileData']) === -1;
/* var a = $location.$$absUrl.split('#')[1];
var patt = new RegExp(a);
var res = patt.test(restrictedPage); */
var loggedIn = $rootScope.globals.currentUser;
if (restrictedPage && !loggedIn) {
$location.path('/login');
}
});
}
use this :based on response from server
.when('/login', {
controller: 'LoginController',
templateUrl: 'view/login.view.html',
resolve:{
logincheck: checklogedin
})
/ resolve function for user....
var checklogedin = function($q ,$http,$location)
{
var deferred =$q.defer();
$http.get('/loggedin').success(function(user){
if (user.staus==true)
{
//goo
deferred.resolve();
}
else
{
deferred.reject();
$location.url('/login');
}
});
return deferred.promise
};
Based on the code that you have provided, I can't tell 100% what is going on in your code. But... you could always try to use the resolve property on each route that you don't want to allow access without authentication. Here is what that would look like for questionBank:
.when('/questionBank', {
controller: 'questionbankController',
templateUrl: 'view/questionbank.view.html',
controllerAs: 'vm',
resolve: {
auth: function(AuthService, $q){
if(AuthService.isAuthenticated()) return $q.resolve();
return $q.reject();
}
}
})
Each property of the resolve object should return a promise, and if that resolves... the route change works. If it rejects... the route change is not allowed. If the promise never resolves, you are screwed, so make sure it resolves or it will never do the route.
This isn't the only way to try what you are saying. It is A way of trying it.
You can also add event listener on your $scope and prevent moving in case of unauthenticated user.
$scope.$on('$locationChangeStart', function (event, next, current) {
if (!is_logged_in) {
event.preventDefault();
}
});
In my code I have two main controllers LoginCtrl and AppCtrl, and all other controllers are nested within AppCtrl. Then in AppCtrl I have this code, which will check for logged user.
if (localStorageService.get('authToken') === null) {
$state.go('login', {locale: CONFIG.defaultLang});
} else if (!userService.isLoggedIn()) {
tokenStorage.setAuthToken(localStorageService.get('authToken'));
userService.setIdentity(JSON.parse(localStorageService.get('user')));
}
As you can see I store auth token from server in local storage. When page loades this code will be executed and if you are not logged in you will be redirected. And because all other application controllers are nested within AppCtrl this code will be executed every time.
For more info about nested controllers try for example this article - https://rclayton.silvrback.com/parent-child-controller-communication

Manually changing the URL does not call the controller in AngularJS

I have a application with main pages as app.html and my controller is app.js. The following is the code in app.js:
angular.module(constants.MODULE_NAME).controller('AppCtrl', function ($scope, $state, $log, $http) {
$scope.role = '';
$http.get("htttp://localhost:8082/service/getUserRole")
.then(function (response) {
$scope.role = response.data.context;
debugger;
if ($scope.role.toLowerCase() == "hr") {
//direct view to hr dashboard
$state.go("app.hr");
} else if($scope.context.toLowerCase() == "eemployee"){
//direct view to employee dashboard
$state.go("app.employee");
}
else{
//do nothing
$state.go("app");
}});
});
So when I run this website the controller is called and based on the value of role the respective dashboard is displayed.When the website runs it hits http://localhost:9080/#/ which is calling the above controller and redirects too http://localhost:9080/#/hr/dashboard (or) http://localhost:9080/#/employee/dashboard.
I have the following in my router.js
export default ['$stateProvider', '$urlRouterProvider', ($stateProvider, $urlRouterProvider) => {
$stateProvider
.state('app', {
url: '/',
template: require('./app.html'),
controller: 'AppCtrl',
controllerAs: 'app'
})
.state('app.hr', {
url: 'hr/dashboard',
template: require('./hr/dashboard/index.html'),
controller: 'HRCtrl',
controllerAs: 'hrctrl'
})
.state('app.employee', {
url: 'employee/dashboard',
template: require('./employee/dashboard/index.html'),
controller: 'EMPCtrl',
controllerAs: 'empctrl'
});
$urlRouterProvider.otherwise('/');
}];
Now when I change the URL to http://localhost:9080/#/ and hit enter then the controller is not getting called. But when I do a refresh the controller gets called. Can I know how I can fix this issue.

Angular Component/Controller resolve $stateprovider

I am trying to adapt to Angular's component (from code generated by Angular Fullstack Generator).
I tried to configure the routes to resolve "query" as per below:
angular.module('paizaApp')
.config(function($stateProvider) {
$stateProvider
.state('main', {
url: '/',
template: '<main query="$resolve.query"></main>',
resolve:{
query:function(){return null;}
},
.state('starred',{
url:'/users/:userId/starred',
template: '<main query="$resolve.query"></main>',
resolve:{
query:function($stateParams){
return {stars:$stateParams.userId};
}
}
})
.state('users',{
url:'/users/:userId',
template: '<main query="$resolve.query"></main>',
resolve:{
query:function($stateParams){
return {user:$stateParams.userId}
}
}
The following are the codes for the controller/component.
class MainController {
constructor($http, $scope, socket, Auth, query) {
this.$http = $http;
this.socket = socket;
this.awesomeThings = [];
$scope.isLoggedIn = Auth.isLoggedIn;
$scope.getCurrentUser = Auth.getCurrentUser;
$onInit() {
this.$http.get('/api/things',{params:{query:query}})
.then(response => {
this.awesomeThings = response.data;
this.socket.syncUpdates('thing', this.awesomeThings);
});
}////////
////////////////////////////////////// etc..
angular.module('paizaApp')
.component('main', {
templateUrl: 'app/main/main.html',
bindings:{query:'='},
controller: MainController
});
I am getting an error message - unknown query provider. However if I remove query from the constructor then the error message is "query is not defined".
Can you please see where I have gone wrong and whether I am supposed to inject the "query" variable into the controller? I am new to Angular 1, not to mention Angular 2.
Update: I have also tried something like this but didn't work:
angular.module('paizaApp')
.config(function($stateProvider) {
$stateProvider
.state('main', {
url: '/',
template: '<main></main>',
resolve:{
query:function(){return null;}
},
controller:function($scope,query){
$scope.query=query
}
And:
angular.module('paizaApp')
.component('main', {
templateUrl: 'app/main/main.html',
controller: MainController,
scope:{query:'='}
});
You shouldn't inject query on controller constructor. You could have do that if you have specified MyController as controller for state.
The query resolve is already passed in component bindings. You can directly get the value of query resolve inside this.query

Resources