I have been working a bit with Angular and I tried to implement simple routing.
I have a basic HTML which contains reference to all the required scripts and a ng-view tag.
For some reason, when the page is loaded, the template isn't shown in the ng-view location. Why isn't it shown, and how to fix it?
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular-route.js"></script>
<script src="routCtrl.js"></script>
</head>
<body ng-app='ngRouteTest'>
<div ng-view></div>
</body>
and the the script file:
var ngRouteTest = angular.module('ngRouteTest',['ngRoute']);
ngRouteTest.config(function($routeProvider){
$routeProvider
.when('/',
{templateUrl : '/routView1.html'})
});
You need to redirect to that page so that routing will come to know which page to render inside ng-view directive.
There are multiple ways to do it.
Define one more otherwise to redirect to /.
$routeProvider.otherwise({redirectTo: '/'})
Add anchor to page that will redirect to /.
<body ng-app='ngRouteTest'>
Home Page
<div ng-view></div>
</body>
Having default url on page in <head> tag.
<base href="/"/>
Okay first you need to run your code from a server, so to test it locally use http-server which is really easy to prepare.
Then you will need to change your templateUrl path from:
{templateUrl : '/routView1.html'}
to:
{templateUrl : './routView1.html'}
After starting a local host and ruining the code from there it worked perfectly fine.
The issue was with the chrome related security when you make local ajax calls.
So one has this problem should do one of the following things:
1.Disable web-security in chrome.
2.Start a local host to test.
Related
I've been banging my head against the problem for embarrassingly long now. I'm using Angular UI Router to handling the routing in a small personal project I'm working on, and I have a strange issue. I have a VERY simple HTML file:
<head>
<title>MY FUN EXCITING PROJECT</title>
<script src='node_modules/angular/angular.min.js'></script>
<script src='node_modules/angular-ui-router/release/angular-ui-router.min.js'></script>
<script src='app.js'></script>
<script src='routes.js'></script>
<script src='dist/auth/authenticationController.js'></script>
<script src='dist/auth/authenticationFactory.js'></script>
</head>
<body>
<H1>I AM A FILE. HELLO.</H1>
<a ui-sref='login'>CLICK ME</a>
</body>
And, again, a VERY simple route provider file:
(function () {
'use strict';
angular.module('project',['ui.router'])
.config(['$stateProvider', function ($stateProvider) {
$stateProvider
.state('login', {
url: '/login',
templateUrl:'dist/auth/authentication.html'
});
}])
})();
And the authentication.html file is literally just a I AM AN AUTHENTICATION PAGE right now.
What's happening is that clicking on the link will cause the address in the address bar to change properly, but the template itself won't render. If I look in the dev tools, though, the page is being sent back from the response (screenshot attached).
I'm using a basic barebones node server to run the server for this, and using
app.use(express.static(__dirname+'/public'));
to serve all the files. Is there something basic I'm missing? I'd infinitely appreciate any help. Thank you!
I've been working on a Chrome extension using angular. I've built off a simple example that uses the browser action popup (popup.html) to host all of my angular code.
On that page, I load all the angular scripts and attach the angular routing:
<script src="bower_components/jquery/dist/jquery.js"></script>
<script src="bower_components/bootstrap/dist/js/bootstrap.js"></script>
<script src="bower_components/angular/angular.js"></script>
<script src="bower_components/angular-route/angular-route.js"></script>
<script src="bower_components/angular-bootstrap/ui-bootstrap-tpls.js"></script>
<script src="scripts/shared/google_auth.js"></script>
<script src="scripts/shared/util.js"></script>
<script src="scripts/app.module.js"></script>
<script src="scripts/app.config.js"></script>
<script src="scripts/filepicker/filepicker.module.js"></script>
<script src="scripts/filepicker/filepicker.controller.js"></script>
<script src="scripts/filepicker/filepicker.factory.js"></script>
<script src="scripts/filepicker/filepicker.components.js"></script>
<script src="scripts/filepicker/filepicker.filecreator.js"></script>
<script src="scripts/notetaker/notetaker.module.js"></script>
<script src="scripts/notetaker/notetaker.controller.js"></script>
<script src="scripts/notetaker/notetaker.factory.js"></script>
<script src="scripts/notetaker/notetaker.component.js"></script>
My app.config.js has the routing setup:
angular.
module('researchBuddyApp').
config(['$locationProvider', '$routeProvider',
function config($locationProvider, $routeProvider) {
$locationProvider.hashPrefix('!');
$routeProvider.
when('/filepicker', {
template: '<filepicker></filepicker>'
}).
when('/notetaker', {
template: '<notetaker></notetaker>'
}).
otherwise('/notetaker');
}
]);
So far I've been mostly writing and testing functionality; now it's time to start to actually start integrating this into the pages where my content is. The plan for the app is to be able to take notes from webpages, so the context menu needs to be able to launch a form.
I've figured out how to setup event handlers for context menus and I've also figured out how to use content scripts and inject code into webpages. But, Chrome blocks access to the local pages of extensions unless explicitly allowed. So there are three solutions that I can see moving forward with, and I am not sure the arguments in favor of each practice.
I could just use my context menu to launch a new chrome window to the appropriate route off of popup.html.
I can add popup.html to "web_accessible_resources" in the manifest file, which will give the content script access to render any part of my angular app inside an iframe.
I can rework how I load my app as demonstrated by angularjs templates in chrome extension so it's loaded throught the manifest.json file and then bootstrapped within the content script itself.
I don't have any idea which of these might be a better approach, and I don't have a great need to actually use the browser_action popup itself.
I'm developing an application in .net mvc with angularjs. When I don't use html5 mode it works fine, but when I set html5 mode to true the server calls that address giving me an he resource cannot be found.
This is my app.js
var app = angular.module("myApp", ['ngRoute'])
.config(function ($routeProvider, $locationProvider) {
$routeProvider.when('/test',
{
templateUrl: 'templates/TestPage.html',
controller: 'ProfesionalController'
});
$routeProvider.otherwise({ redirectTo: '/' });
$locationProvider.html5Mode(true);
});
And this is my view (layout):
<!DOCTYPE html>
#Scripts.Render("~/bundles/modernizr")
<script src="~/Scripts/angular/angular.js"></script>
<script src="~/Scripts/angular/angular-route.js"></script>
<script src="~/app/app.js"></script>
<script src="~/app/home/home.js"></script>
<script src="~/app/profesional/profesional.js"></script>
<base href="/">
Test
#*this is the link*#
</div>
</div>
</div>
<div ng-app="myApp" class="container body-content">
<div ng-view></div>
#RenderBody()
</div>
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/bootstrap")
#RenderSection("scripts", required: false)
When I click to test link the server try to locate:
http://localhost:39881/test" giving me an 404 Not Found - http://localhost:39881/test"
What I'm missing. It works well with no html5 mode.
Even I was facing the same issue when I was trying to enable html5 mode in my application. Later when I saw the entire code carefully, I came to know the name of my API call and my route call were same. The browser was getting confused and instead of calling route call it was calling the api call.
Try changing either of the name. It should work fine.
You need to configure your server side rewrites so it doesn't try to load up pages at that path. See details for your server type here: https://github.com/angular-ui/ui-router/wiki/Frequently-Asked-Questions#how-to-configure-your-server-to-work-with-html5mode
Something that cost me a lot of time that hopefully will help others if you are using Azure and a pure ng app:
I am using Azure and Angular and hit the same problem. I had the IIS Rewrite rules to redirect all requests to the index.html file as per the documentation in ng.
However, it still was not working on production, only on local. It turned out to be a stupid user error - my Angular webapp is a pure HTML/JS app (ie. no ASP.NET MVC) and the Azure Publishing Profile had not marked the web.config for dpeloyment to the cloud. I used Kudu on Azure to check the webapp and there was no web.config on live, hence the rewrite rules were not being considered... changing it to FileType Content solved the issue so the web.config was deployed correctly and the routing now works..
I have html file which implements AngularJS routes as follows,
index.html:
<!DOCTYPE html>
<html ng-app="demo">
<head>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div ng-view>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script>
<script src="http://code.angularjs.org/1.2.1/angular-route.min.js"></script>
<script>
// Code goes here
var demo = angular.module('demo', ['ngRoute']);
demo.config(function($routeProvider){
$routeProvider.when('/', {
controller: 'testController',
templateUrl: 'test.html'
})
})
var controllers = {};
controllers.testController = function($scope){
$scope.first = "Info";
$scope.customers=[
{name:'jerry',city:'chicago'},
{name:'tom',city:'houston'},
{name:'enslo',city:'taipei'}
];
}
demo.controller(controllers)
</script>
</body>
</html>
test.html:
<div>
<input type="text" ng-model="name"/>
</br>
{{first}}
</br>
<ul>
<li ng-repeat="cust in customers | filter:name">{{cust.name | uppercase}} - {{cust.city}}</li>
</ul>
</div>
You can find the working version here
But why is it not working when I run the same in my local browser :(
Here is the chrome console error:
Any help appreciated! :)
It is important to make it clear. For security reasons, Chrome (for example) won't allow you to load local files (ie: the templates for your views). My suggestion is to set up a web server to test your applications:
Use the free edition of the Visual Studio Express for web development.
Use gruntjs to quickly set up your project.
Alternatively you can use inline templates in place of loading it externally, but it does not seems to be a good practice.
Edit:
Using the console error print that you posted, Chrome is blocking your ajax request. You can bypass this restriction using a command line argument:
chrome.exe --allow-file-access-from-files
However I would encourage you to set up a simple local web server, It will prevent you for some headaches while your are learning...
You can use Firefox for test. Route and ajax will work.
But it is better to set up a web server like #gustavodidomenico said
the work around to make ng-view work in local is to put the content of other htmls in the script tag as
<script type="text/ng-template" id="index22.html">
This is index 2 template.
</script>
<script type="text/ng-template" id="index33.html">
This is index 3 template.
</script>
in the same HTML from where the call is being made.
ngview makes an AJAX call to load the content of external HTMLs or seperate HTMLs , chrome does not allow AJAX call for local resources , IE 11 also shows 'Access is denied' error message.
when including in script tags , this AJAX call is not made.
There is a Chrome Extension called Web Server for Chrome. you can add it and then lunch it, in browse dialog choose your working folder, then it gives you a Local URL, you can test your app there.
I have an angularjs SPA application with an index.html page as the main template and the rest of the views are loaded as subviews in an ng-view tag. I'm using a twitter bootstrap template for the site so the template has a login page thats different from the rest of the pages. Is there a way to have multiple main template pages, one for the login page and one for everything else? I've been trying to figure out how to specify a different page in the route provider but I haven't been able to figure out how to specify a page rather than a partial view as the templateURL or if thats even possible.
I'm new to angularjs so i'm not sure what the best way to handle this situation.
Thanks
You are on the right track with RouteProvider
angular.module('mymodule', ['ngRoute'])
.config(function($routeProvider) {
$routeProvider.
when('/index.html/page1/', {templateUrl : './templates/template1.html'}).
when('/index.html/page2/', {templateUrl : './templates/template2.html'}).
otherwise({redirectTo : '/index.html/page1/'});
});
You would have to do this using ng-include. Your main view should look like
<body ng-app>
<div id='topNav' ng-include='templateUrl' ng-controller='topNavController'></div>
<div id='left' ng-include='templateUrl' ng-controller='leftNavController'></div>
<div ng-view>
</body>
The templateUrl can be from server or preloaded onto the client using <script> tag.
The javascript would look like.
function topNavController($scope, $route, $location) {
//Check using $route or $location if login view is loaded
// if yes $scope.templateUrl='loginTopNavTemplateUrl'
//else $scope.templateUrl='mainNavTemplateUrl'
}
Check documentation for ng-include, $route and $location to see how how these elements work.