I am learning angular.js and found an example on w3c.school
http://www.w3schools.com/angular/tryit.asp?filename=try_ng_routing
But when I try to test it it doesn't work,
I made two .htm files simply containing one word, for example "RED", or "GREEN". As simple as this example is I cannot get it to work. I think that it might be the libraries I am using
<!DOCTYPE html>
<html>
<!-- JavaScript Files -->
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular-route.js"></script>
<body ng-app="myApp">
<p>Main
</p>
Red
Green
Blue
<div ng-view></div>
<script>
var app = angular.module("myApp", ["ngRoute"]);
app.config(function($routeProvider) {
$routeProvider.when("/", {
templateUrl: "test.html"
}).when("/red", {
templateUrl: "red.htm"
}).when("/green", {
templateUrl: "green.htm"
});
});
</script>
</body>
</html>
In this case you are moving towards a page "red.htm" which,... Doesn't exist in your situation! The page is already there in the directory for W3School (http://www.w3schools.com/angular/red.htm for exmaple)
So what you need to do is to create a htm page called red.htm in the same directory and thus navigate to it using routing. If you want to make the same example copy the code of the page I linked and try to run it with both files on the same directory.
From the three files I was using (test.html, red.html, green.html) I finally noticed/understood that you mustn't self-reference the file you are writing the script in.
<script>
var app = angular.module("myApp", ["ngRoute"]);
app.config(function($routeProvider) {
$routeProvider.when("/red", {
templateUrl: "red.htm"
}).when("/green", {
templateUrl: "green.htm"
});
});
</script>
Simply by removing the .when method for 'test.html' (which is the exact same file the code is in) the self-referencing stops, and the code is allowed to execute.
Related
https://codepen.io/a_shokn/pen/yEJpww?editors=1010
var myApp = angular.module('myApp', ['ngRoute']);
myApp.config(function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'main.html'
})
.when('/second',{
templateUrl:'second.html'
})
});
Here is the Link to my Code Snippet , My Question is Were Must we keep our files (in my case main.html and second.html) when using routing in anjular js
As per my understanding, codepen doesn't support adding multiple files. You may try moving your code to plunker instead. Alternatively, you can try to use inline templates in the HTML. For example, to have main.html resolved, you may write this snippet in the HTML:
<script type="text/ng-template" id="main.html">
// contents of main.html
</script>
This will make AngularJS resolve the template using this script tag. You can find a working demo of your code here.
I am using templates to build my app. Basically have one main page, and then I am loading others pages thru it using ng-view. The href links in the index.html work fine. But I also want to be able to change ng-view within js functions as well. How is this done?
I tried to go to the red page using $location.path, but nothing seems to happen besides printing to the console. Before that i tried using $window.location.href(), which did go to the page, but dropped the index.html container, breaking the app.
edit:
As pointed out in Siddhesh's answer comments, it works if not used with $locationProvider.html5Mode(true);. But I would like to keep clean urls. So I'm looking for a way to keep it, IF that's possible.
index.html
<head>
<base href="/testing/onetest/">
<script>
app.controller('masterController',function($location){
setTimeout(change, 3000);
function change() {
console.log("changing in 3 seconds");
$location.path('/red');
}
});
</script>
</head>
<body ng-app="app" ng-controller="masterController">
Main
Red
Green<br>
<div ng-view></div>
</body>
app.js
var app = angular.module("app", ["ngRoute"]);
app.config(function($routeProvider,$locationProvider) {
$routeProvider
.when("/", {
templateUrl : "home.html",
controller : 'mainController'
})
.when("/red", {
templateUrl : "red.html"
})
.when("/green", {
templateUrl : "green.html"
});
$locationProvider.html5Mode(true);
});
For angular js version less than 1.6
$window.location.href= '#red';
For angular js version 1.6 or more
$window.location.href= '#!red';
Try this and see if it works. This might help you to change the ng-view from function. It worked for me.
I have a website by mean-stack.
Normally, all my external references are listed in index.html
I realize that one external JS library (e.g., https://cdnjs.cloudflare.com/troublelibrary.js) I am using has some conflit with a part of my website. So a workaround I am looking for is to NOT load it for a specific path https://www.myexample.com/specific.
Does anyone know how to achieve this in the routing?
Edit 1: (see the full question here)
Actually, the library that has conflit is history.js. My initial code which loads it all the time is as follows. As a result https://localhost:3000/home in a browser is always https://localhost:3000/home (i.e., will not add # because of history.js)
<script src="https://appsforoffice.microsoft.com/lib/1/hosted/office.js"></script>
<script src="https://cdn.rawgit.com/devote/HTML5-History-API/master/history.js"></script>
Then, if I try the following code, as Ben suggests:
<script src="https://appsforoffice.microsoft.com/lib/1/hosted/office.js"></script>
<script>
var newScript = document.createElement('script');
newScript.src = 'https://cdn.rawgit.com/devote/HTML5-History-API/master/history.js';
document.head.appendChild(newScript);
console.log(window.location.href)
</script>
I realize that for the first time of loading https://localhost:3000/home will not change. But, if I refresh the browser, it can change to https://localhost:3000/#/home.
So appending the script is not exactly the same as a direct reference, does anyone know why?
I see your problem in a different perspective. You mentioned that you use the history.js to avoid # on the URL. But you do not need history.js to do that. I think you understood your problem in the wrong way. There is an inbuilt Angular functionality to get rid off # paths. Because # is used to keep track of the relative path on any route. If we want we can override that default functionality.
But if you use this approach the server should responsible to redirect the user to index or home page on any application route since Angular handle all the routing in the application.
First you should add
<base href="/" />
in your HTML file.
Then you should enable HTML5 Mode inside Angular application as follows.
$locationProvider.html5Mode(true);
By adding these two attributes you can get rid off the # path and this is the recommended way.
Following is a complete example.
var app = angular.module("app", ["ngRoute"]);
app.controller("MainController", function($scope){
});
//Add route handler
app.config(["$routeProvider", "$locationProvider", function ($routeProvider, $locationProvider) {
$routeProvider
.when('/', {
template: '<h1>Home</h1>',
reloadOnSearch: true
})
.when('/about', {
template: '<h1>About</h1>',
reloadOnSearch: true
}).otherwise({
redirectTo: '/'
});
// This will remove hash bang from the routes
$locationProvider.html5Mode(true);
}]);
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.10/angular-route.js"></script>
<base href="/" />
</head>
<body>
<div>
Home
About
</div>
<div ng-app="app" ng-controller="MainController">
<ng-view></ng-view>
</div>
</body>
</html>
As you can see on the above example when you click on the about link the server responds with not found on /about. This means the # bang is removed.
This is one way to do it:
if(window.location.href !== 'https://url.com/path/to/trouble/page'){
var newScript = document.createElement('script');
newScript.src = 'https://url.com/path/to/script';
document.head.appendChild(newScript);
}
Add this to the <head> of the document. It will not load the trouble script on the page you specify in the if statement. Make sure not to load the trouble script anywhere else on the page as well.
you can do lazy loading of script in angular
<script type="text/javascript" ng-src="{{exUrl1}}"></script>
and somewhere in your code (based on whatever logic you want)
$rootScope.exUrl1 = $sce.trustAsResourceUrl(confserver.example.url);
I have spent hours and hours searching and googling to find out why my ngRoute is not working but couldn't find the solution so i decided to come here. Here is my code::
"app.js"
angular.module("sandwichApp",["cart", "ngRoute"])
.config(['$routeProvider', function($routeProvider){
$routeProvider
.
when("/",{
templateUrl: "app/views/sandwichList.html",
controller: "SandwichListController"
}).
when("/sandwichList",{
templateUrl: "app/views/sandwichList.html"
}).
when("/checkout",{
templateUrl: "app/views/cart.html"
}).
otherwise({
redirectTo: "/app/views/sandwichList.html"
});
}]);
// for this particular code i have tried the version where the config() doesn't contain array "[]" but only the function and it also doesn't work
"sandwichListController.js"
var main = angular.module("sandwichApp", ["clientAppServiceModule"]);
main.controller("SandwichListController", function($scope, ClientAppService, cart){
$scope.original = {
sandwiches : []
}
//.... more code here. THERE IS NO PROBLEM WITH THIS CONTROLLER SO THE CODE IS NOT IMPORTANT.
);
"index.html"
<!DOCTYPE html>
<html ng-app="sandwichApp">
<head>
<meta charset="UTF-8">
<title>title</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular-route.js"></script>
<!--script src="https://cdn.jsdelivr.net/angularjs/1.5.5/angular-route.min.js"></script-->
<script src="app.js"></script>
<script src="app/services/clientAppService.js"></script>
<script src="app/controllers/sandwichListController.js"></script>
<script src="app/model/cart.js"></script>
</head>
<body ng-controller="SandwichListController">
<div><strong>Heading & Cart</strong></div>
<div ng-view></div>
</body>
</html>
"sandwichList.html"
<div>
<b>Your Cart: </b>
{{totalItems}} items / {{totPrice | currency}}
<span>checkout</span>
</div>
<div>
<input type="text" ng-model="sandwichName" ng-change="filterSandwich()"/>
</div>
<div>
<h1>Sandwiches </h1>
</div>
<div ng-repeat="sandwich in workingCopy.sandwiches">
<h3 ng-click="addItemToCart(sandwich)">
<strong>{{sandwich.Name}}</strong>
<span>{{sandwich.Price | currency}}</span>
</h3>
</div>
When i load the "index.html" page, i expect the "otherwise" section of the routeer to display the "sandwichList.html" in the <div ng-view></div> section but it doesn't work. If it can't find the file, it will complain but it doesn't complain meaning that the file is at the right location. Yet it does not work.
In the sandwichList page at least if the controllers will not work, it must be able to display the <h1>Sandwiches </h1> .
My chrome console doesn't display any errors so i don't know what is causing the problem
I think it might be because you are accidentally declaring your app twice. When registering a new module in angular you provide it a second parameter which is an array of dependencies. You are doing that where you specify your routes. However, when you go to create your controller, you're code is this:
var main = angular.module("sandwichApp", ["clientAppServiceModule"]);
Angular sees the dependencies and assumes it is to create a new app. When it realizes there is already one with the same name, it overwrites it and you lose all the route stuff you setup. Try passing your "clientAppServiceModule" to the initial app definition, then just creating your controller by doing this:
angular.module("sandwichApp").controller("SandwichListController", function($scope, ClientAppService, cart){
$scope.original = {
sandwiches : []
}
//.... more code here. THERE IS NO PROBLEM WITH THIS CONTROLLER SO THE CODE IS NOT IMPORTANT.
);
Let me know if you have any questions, or if that doesn't solve it.
I tried some simple Angular Routing, but I cant specify what's the error. Chrome just tells me that Angular can't compile the Template.
In the following Link you can see my directory structure.
directory-structure
-- angular.js
var testApp = angular.module('testApp', ['ngRoute']);
testApp.config(function($routeProvider){
$routeProvider.when('/list', {
templateUrl: 'pages/list.html',
controller: 'mainController'
}).when('/insert', {
templateUrl: 'pages/new.html',
controller: 'newController'
});
});
testApp.controller('mainController', function($scope){
$scope.message = 'main';
});
testApp.controller('newController', function($scope){
$scope.message = 'new';
});
--index.html
<!DOCTYPE html>
<html lang="en" ng-app="testApp">
<head>
<meta charset="UTF-8">
<title>Barfly</title>
<script src="/angular/angular.min.js"></script>
<script src="/angular-route/angular-route.min.js"></script>
<script src="/js/angularApp.js"></script>
</head>
<body ng-controller="mainController">
list
new
<div id="main">
<div ng-view></div>
</div>
</body>
</html>
This is my error,
Browser Error
Thank you in advance!
EDIT. Sorry, I didn't see your directory structure. Are you sure pages directory is accessible to the public? Should the pages directory be moved into public directory?
Old answer:
The error is saying the templateUrl /pages/list.html does not exists. You should either save a template file into /pages/list.html file or add an inline template in the html body like this:
<script type="text/ng-template" id="/pages/list.html">
my template here
</script>
I encountered a sort of similar problem: templateUrl files could be not loaded (all resources didn't). In my case it happened when app was loaded on a browser on a mobile device. It was caused by Content Security Policy restrictions (How does Content Security Policy work?)
I got the CSP to permit all resources except for the templates referenced by templateUrl.
I also tried loading the templates through the script directive (https://docs.angularjs.org/api/ng/directive/script), but to no avail.
Eventually I decided to embed the templates in the route itself, like this:
testApp.config(function($routeProvider){
$routeProvider.when('/list', {
template: '<li ng-repeat="etcetera"></li>',
controller: 'mainController'
});
});
<a data-target="#list">list</a>
<a data-target="#insert">new</a>