I have
<base href="/!#/">
at the top of my index.html file. When I go to URL http://localhost:5000/ everything works fine, it instantly add #!/ so the URL is http://localhost:5000/#!/ and page display as expected.
At the server side I have following code which should allow me to use my files
app.use(express.static(path.join(__dirname, 'public')));
Structure of my files is something like:
bookApp(folder)
server.js
public(folder)
index.html
app.js(ngRoute)
views(folder)
css(folder)
controllers(folder)
and my AngularJS routing is:
(function () {
'use strict';
angular
.module('app', [
'ngRoute'
])
.config(config);
function config ($routeProvider) {
$routeProvider
.when('/', {
controller: 'PostsCtrl',
templateUrl: 'views/posts.html'
})
.when('/register', {
controller: 'registerCtrl',
templateUrl: 'views/register.html'
})
.when('/login', {
controller: 'loginCtrl',
templateUrl: 'views/login.html'
})
.otherwise('/');
}
})();
The very first page (views/posts.html) load as expected but when I click
<li>Sign in</li>
the URL is http://localhost:5000/login not as like I thought http://localhost:5000/!#/login.
and it display:
Cannot GET /login
when I manually change URL to http://localhost:5000/#!/login it works fine.
How to fix this behavior?
The only solution I see is to get rid of <base> tag and in every link manually in href directive add !# before slash.
It looks like you are forgetting the ng-view directive: <div ng-view></div> which is the container for the content that is provided by your routing. Place this above your script if you have everything contained in one file.
You can also try:
<ng-view></ng-view>
<div class="ng-view"></div>
Is there any particular reason you are still using Angular 1? I know this isn't technically answering your question, but I would highly recommend that you start using the latest Angular. You can still keep legacy code but it will make a lot of what you are doing a lot cleaner and clear.
Related
I am using AngularJS in my MVC application. I am facing the very common routing issue where !# appears in the URLs. I have looked out for solution and found this solution almost in every accepted answer which fails miserably in my case.
I have used this line of code inside my routing:
$locationProvider.html5Mode(true).hashPrefix('!');
This line doesn't change anything. I tried this one as well:
$locationProvider.html5Mode(true);
but no luck.
Also, I used this tag inside my <head> tag:
<base href="/">
This line doesn't change anything as well.
My routing code and navigation code is given below:
app.config(function ($routeProvider, $locationProvider) {
$routeProvider
.when("/", {
templateUrl: "payment/MakePayment",
controller: "paymentController"
})
.when("/SearchPayment", {
templateUrl: "payment/SearchPayment",
controller: "paymentController"
})
.when("/Flush", {
templateUrl: "payment/InvalidateCacheForIndexAction",
controller: "paymentController"
});
$locationProvider.html5Mode(true).hashPrefix('!');
});
Navigation code-
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li>Make Payment</li>
<li>Search Payment</li>
<li>Flush</li>
</ul>
</div>
When site is launched I see http://localhost:56810/ in browser. When I click on Search Payment link the URL in browser reads http://localhost:56810/#!#SearchPayment. Same thing happens for Flush as well. Also the navigation doesn't take place. That means the change in URLs doesn't get handled by given routeProvider routes.
Just use
$locationProvider.html5Mode(true).hashPrefix('');
and remove #
<li>Search Payment</li>
<li>Flush</li>
OR
Just use following so that you dont have to configure your server side for only handling "/"
$locationProvider.html5Mode(false).hashPrefix('');
and remove #
<li>Search Payment</li>
<li>Flush</li>
I am following a book called MEAN Machine. The code from the part in this book in question can be found at this Github Repo.
When clicking the links in /public/views/index.html which should be routed, I get file not found errors in the web browser.
The code (/public/js/app.routes.js) that does not seem to work:
// inject ngRoute for all our routing needs
angular.module('routerRoutes', ['ngRoute'])
// configure our routes
.config(function($routeProvider, $locationProvider) {
$routeProvider
// route for the home page
.when('/', {
templateUrl : 'views/pages/home.html',
controller : 'homeController',
controllerAs: 'home'
})
// route for the about page
.when('/about', {
templateUrl : 'views/pages/about.html',
controller : 'aboutController',
controllerAs: 'about'
})
// route for the contact page
.when('/contact', {
templateUrl : 'views/pages/contact.html',
controller : 'contactController',
controllerAs: 'contact'
});
$locationProvider.html5Mode(true);
});
In the index.html file, we are pointing to the correct files:
<script src="js/app.routes.js"></script>
<script src="js/app.js"></script>
To test their code, I changed the base tag in index.html to my folder's path which eliminated errors of not finding the above files.
Is this material dated? Also, I realize this book is not using Angular 2. Does Angular 2 vary drastically in routing and is this material deprecated?
Simply run command
node server.js
from '12-angular-routing' directory and open in browser http://localhost:8080
The problem is that browsers by default does not allow AJAX requests to files located on your local file system. In this case you should run your local server which serves client application(server.js is simple express server).
I have a rootScope json array that's viewed is several controllers, and gets updated in yet another controller. The json array contains urls that get updated. The view controllers show updated urls about half the time, but if I reload the page, I do get updated views 100% of the time.
I have tried using $scope.$apply() and $timeout, but they made no difference.
Could someone please tell me what angular tools are out there for this? I'm hoping there is a simple approach to it.
Going off of my earlier comment:
Index
<!doctype html>
<html ng-app="myapp">
<head>
<!--Head stuff-->
</head>
<body>
<div ng-view=""></div>
<!-- Scripts, other stuff -->
</body>
</html>
Main Script
'use strict';
angular
.module('myapp', [
//...
'ngRoute',
//...
])
.config(function (..., $routeProvider, ...) {
$routeProvider
.when('/404', {
templateurl: '404.html',
controller: 'ErrorCtrl',
controllerAs: 'errorCtrl',
title: 'You are lost'
})
.when('/', {
templateUrl: 'views/home.html',
controller: 'HomeCtrl',
controllerAs: 'homeCtrl',
title: 'Home'
})
.when('/contact', {
templateUrl: 'views/contact.html',
controller: 'ContactCtrl',
controllerAs: 'contactCtrl',
title: 'Contact Us'
})
.otherwise({
redirectTo: '/404'
});
//...
})
.run (function (...) {
//...
});
Usage
Contact Us
You'd be taking all of the base template code that's common to your pages and be including that on index. Basically, the stuff that doesn't change will always be there. Otherwise, take it off of the main page and put it into a template file with its own controller. Alternatively, have some shared controllers and just use the views as templates, then shovel all of the functionality into directives. I actually prefer the latter method, but the former is shown above.
What's noteworthy about this solution is that the page is only actually loaded once. Since you stay on the index whenever you navigate to a different view, you only need to grab the HTML for the new template from your server and inject it into the view (which ngRoute takes care of). I believe that by default you'll have a # in your URL, so you'll probably want to enable HTML5 mode.$locationProvider into your config function and then add this line:
$locationProvider.html5Mode ({ enabled: true });
You also need to add a base to the head element of your index file:
<base href="/" />
Homework: Routes tutorial, HTML5 mode
If you use Grunt, you might also want to look into ngTemplates. It can really boost performance.
I trying to make an application that contains multiple views as template. The templates are under the js/app/pages/ folder. And I have 2 templates to show and route. My routing section is:
var app = angular.module("myApp", ['ngRoute', 'ngMaterial']);
app.config(function ($routeProvider, $locationProvider) {
$routeProvider
.when('/Page', {
templateUrl: 'js/app/pages/Page.html',
controller: 'pageController',
reloadOnSearch: false
})
.when('/Settings', {
templateUrl: 'js/app/pages/Settings.html',
controller: 'settingsController',
reloadOnSearch: false
})
.when('/Admin', {
templateUrl: 'js/app/pages/Admin.html',
controller: 'adminController',
reloadOnSearch: false
})
.otherwise({
redirectTo: '/Page'
});
$locationProvider.html5Mode(true);
});
And my html file contains
<div id="menu"></div>
<div ng-view></div>
Menu div contains menu elements that route me between the pages. For example, when I run this site on browser, URL will be localhost/Page, and when I click the settings button URL change with localhost/Settings. But when I press the F5 button in my keyboard. Page gives me error The resource cannot be found..
I search on the internet "how to refresh routing page in angularjs" and find some solutions but I couldn't make them work for me. I tried $route.reload() and $routeUpdate() method but that does not work for me. Maybe I'm wrong in something.
If you are using Apache server this should work run this in terminal
sudo a2enmod rewrite && sudo service apache2 restart
works for me
Solved! I couldn't manage refresh with ngRoute. Then i convert it into ui-router. I declare the states by urls. And the refresh is working. Thanks for comments and answers. Maybe this will help someone.
Actually when you are pressing F5 from keyboard, it is hitting to your server for that page, not angular because you don't have any # sign between your URL. For angular, URL should be like as - localhost/#/Page
Use html5mode
A great article about it here
to init its very simple
.config(function($routeProvider, $locationProvider) {
// other routes here
$locationProvider.html5Mode(true);
});
When you "reload a page", you whole app will reinit again. That means if you are not on the main page, and the sub route you are at missing some data, you will likely get an error.
You should look into resolve attribute for routes, so for example,
.when('/Settings', {
templateUrl: 'js/app/pages/Settings.html',
controller: 'settingsController',
reloadOnSearch: false,
resolve: {
resourceone: function(){return whatsneeedtoberesolvehere;}
}
})
that way no matter where your app is reloaded, it will have the necessary data to boot the page
Just keep the # in URL, you don't have to put extra effort to manage reloads etc. you can think a "#" in URL represent a specific state in single page application.
Otherwise it can be managed by module rewriting, that map the url with hashed version URL internally for AngularJs app.
I have installed my Angular App in a location like this:
http://example.com/my-app
My App routing is like this:
var myApp = angular.module('myApp', ['ngRoute','ngAnimate', 'ui.bootstrap', 'angularFileUpload']);
myApp.config(['$routeProvider', function($routeProvider) {
$routeProvider
.when('/templates', {
controller: 'TemplatesController',
templateUrl: '/components/com_myApp/myApp/views/templates/template-list.html'
})
.when('/apps', {
controller: 'AppController',
templateUrl: '/components/com_myApp/myApp/views/apps/app-list.html'
})
.otherwise({
redirectTo: '/templates'
});
}]);
Now what happens is, when I go to http://example.com/my-app, the url instead of showing http://example.com/my-app#/templates it is showing as http://example.com/templates
It seems the otherwise condition is basically removing the base directory my-app# from the url. I have been scratching my head over this and after reading I also tried adding base url to head tag and tried changing the myApp.config to this:
myApp.config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
$locationProvider.html5Mode(true);
....
}
But although the routing seems to work when using $locationProvider like the above, the base url is still not showing the way I want it. The url is showing like this http://example.com/templates without my-app in the url path. I dont want Angular to remove the base path from the URL and I want the urls to show like this http://example.com/my-app/..xyz...
Why is Angular doing this?
This is happening because you've instructed Angular to not use hashbang URLs by specifying $locationProvider.html5Mode(true). Remove or otherwise comment out that code snippet and if you specified <base href="/"> in your root template file, remove or comment out that also and just use ngRoute without those.