My SPA does not load in AngularJS using Routing - angularjs

I have just started getting into AngularJS and was following the guide AngularJS in 60 Minutes by Dan Wahlin up to page 79. However, I’m only presented with my homepage which is blank by default; it does not load my view1.html which it should, according to the guide. I’ve been trying to locate the problem but cannot find it.
Unlike this guide, though, I’m not running the program through localhost but through file:///Users/.../home.html.
My code so far in home.html:
<!DOCTYPE html>
<html data-ng-app="demoApp">
<head>
<title>Lekstuga</title>
</head>
<!-- _________________________________( Home )_________________________________ -->
<body>
<div>
<div data-ng-view></div> //here it should load Partials/view1.html
</div>
<!-- _________________________________( Scripts )________________________________ -->
<script src="AngularJSDemos/Scripts/angular.js"></script>
<script>
var demoApp = angular.module('demoApp', []);
demoApp.config(function ($routeProvider) {
$routeProvider
.when('/',
{
controller: 'SimpleController',
templateUrl: 'Partials/View1.html'
})
.when('/view2',
{
controller:'SimpleController',
templateUrl: 'Partials/View2.html'
})
.otherwise({ redirectTo: '/view1' });
});
demoApp.controller('SimpleController', function ($scope) {
$scope.customers = [
{name: 'Kalle Anka', city:'Duckville'},
{name: 'Pelle Andersson', city: 'Pelletown'},
{name: 'Pelle Eriksson', city:'Pelletown'},
{name: 'Kajsa Larsson', city: 'Kajskroga'}
];
$scope.addCustomer = function () {
$scope.customers.push(
{
name: $scope.newCustomer.name,
city: $scope.newCustomer.city
});
};
});
demoApp.controller('SimpleController', SimpleController);
</script>
<!-- _________________________________( END )_________________________________ -->
</body>
</html>
Followed by my code in View1.html:
<div class = "container">
<h2>View 1</h2>
Name:
<br />
<input type="text" data-ng-model="filter.name" />
<br />
<ul>
<li data-ng-repeat="cust in customers | orderBy:'city' | filter:filter.name">
{{ cust.name }} - {{ cust.city | uppercase }}</li>
</ul>
<br />
Customer Name:<br />
<input type="text" data-ng-model="newCustomer.name" />
<br />
Customer City:<br />
<input type="text" data-ng-model="newCustomer.city" />
<br />
<button data-ng-click="addCustomer()">Add Customer</button><br />
View 2
</div>

When you say:
templateUrl: 'Partials/View1.html'
Angular looks in the same place where your index.html is. You probably have placed 'Partials' folder in app/views or something like that. Just provide the full path relative to the folder where 'index.html' is located.
But in general – may I suggest you to run a local webserver with nginx or MAMP or just use Yeoman http://yeoman.io/. This will make your life much easier.

There has been a change as of version 1.2 : the routing functionality has been moduled out.
The fix however is simple enough :
Load the new javascriptfile in your code : <script src=".yourjs/angular-route.js"></script> You can download it here http://code.angularjs.org/1.2.9/ (other versions other paths of course)
Indicate the 'ngRoute' dependency in your code : var demoApp = angular.module('demoApp', ['ngRoute']);

Related

ui-router Main View is rendering thrice and no controller are registering

I am trying to create a SPA using angular ui-router with MVC. I am facing three issues.
1.The controllers OfferController.js and OfferCustomizationController.js are not registering.
2.I am getting the errors ' No reference point given for path '.offer', No reference point given for path '.customizations'.
3. Main view is rendering thrice.
I have no clue what am i missing. Please help.
I have included the following files in my Layout.cshtml:
<script src="#Links.Scripts.angular_min_js"></script>
<script src="#Links.Scripts.ProductCatalog.app_js"></script>
<script src="#Links.Scripts.ProductCatalog.service_js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.10/angular-ui-router.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular-animate.min.js"></script>
I have made two views. Offers And OfferCustomizations. And a main view. Following is my code for the main view:
<div class="inside-data-div" ng-app="ProductCatalog">
#*<div ui-view></div>*#
<div class="col-lg-12">
<div class="row">
<div class="col-sm-8 col-sm-offset-2">
<div id="form-container">
<div class="page-header text-center">
<h2>Create Offer</h2>
<!-- the links to our nested states using relative paths -->
<!-- add the active class if the state matches our ui-sref -->
<div id="status-buttons" class="text-center">
<a ui-sref-active="active" ui-sref=".offer"><span>1</span> Offer Details</a>
<a ui-sref-active="active" ui-sref=".customizations"><span>2</span> Offer Customizations</a>
</div>
</div>
<!-- use ng-submit to catch the form submission and use our Angular function -->
<form id="signup-form" ng-submit="SaveForm()">
<!-- our nested state views will be injected here -->
<div id="form-views" ui-view></div>
</form>
</div>
<!-- show our formData as it is being typed -->
<pre>
{{ formData }}
</pre>
</div>
</div>
</div>
</div>
Following is my code of app js:
var productCatalogApp = angular.module('ProductCatalog', ['ui.router']);
productCatalogApp.value('appName', 'Product Catalog');
productCatalogApp.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
// route to show our basic form (/form)
.state('wizard', {
url: '/wizard',
templateUrl: 'WizardSubForm',
controller: 'WizardMainController'
})
// nested states
// each of these sections will have their own view
// url will be nested (/form/profile)
.state('wizard.offer', {
url: '/offer',
templateUrl: 'OfferForm',
controller: 'OfferCtrlr'
})
// url will be /form/interests
.state('wizard.customizations', {
url: '/customizations',
templateUrl: 'OfferCustomizations',
controller: 'CustomizationCtrlr'
});
// catch all route
// send users to the form page
$urlRouterProvider.otherwise('/wizard/offer');
});
productCatalogApp.controller('WizardMainController', function ($scope) {
// we will store all of our form data in this object
$scope.formData = {};
// function to process the form
$scope.SaveForm = function () {
alert('awesome!');
$scope.formData = { "Offer": $scope.offer, QuestionGroups: $scope.QuestionGroups }
};
});
This is how i'm registering my controllers. Below is the one for offercontroller.
var app = angular.module('ProductCatalog.controllers', []);
app.controller('OfferCtrlr', function ($scope, $http, $modal) {
});
Any help will be appreciated.

AnguarJS Routing Not Working As Expected

I have a listing of blog posts and I want to be able to click on the title and have it dynamically redirect to the proper posting.
So far it works except when I click on the anchor tagged title it redirects to:
blog/#/post/:post
rather than
blog#/post/:post
I've tried to change the href to data-ng-href,
using target="_self"
and tried changing the href="#/post/{{post}}" and href="/post/{{post}}"
Routes:
(function(){
'use strict';
angular.module('ghpg')
.config(Config);
Config.$inject = ['$routeProvider'];
function Config($routeProvider){
$routeProvider
.when('/listing', {
templateUrl: '/angular/views/listing.client.view.html'
}).otherwise({
redirectTo:'/'
}).when('/post/:title',{
templateUrl: '/angular/views/post.client.view.html',
controller: 'postController',
controllerAs: 'post'
}).otherwise({
redirectTo:'/listing'
});
}
})();
Listing View:
(function(){
'use strict';
angular
.module('ghpg')
.controller('listingController', listingController);
listingController.$inject = ['$scope', 'blogContent'];//,'blogContent'] //, 'blogContent'];
////
function listingController($scope, blogContent){
var vm = this;
vm.articles = [];
grabData();
function grabData(){
return blogContent.getContent().then(function(data){
console.log(data.articles);
vm.articles = data.articles;
return vm.articles;
},function(err){
console.log(err);
vm.data = [];
});
}
}
})();
App.js:
(function(){
'use strict';
var dependencies = [
'ghpg',
'ngRoute'
];
angular.module('blogger', dependencies)
.config(Config);
Config.$inject = ['$locationProvider']
function Config($locationProvider){
$locationProvider.hashPrefix('!');
}
if (window.location.hash === '#_=_'){
window.location.hash = '#!';
}
//bootstrap angular
angular.element(document).ready(function(){
angular.bootstrap(document, ['ghpg']);
});
})();
LISTING VIEW:
<div class="container-fluid" data-ng-Controller="listingController as vm">
<h2> Listings </h2>
<div class="row">
<div class="col-md-4"></div>
<div class="col-md-8">
<div class="post-listing" data-ng-repeat="post in vm.articles">
<h3 class="article-title"><a target="_self" data-ng-href="/blog#/post/{{post.title}}"> {{ post.title }} </a></h3>
<div class="article-container">
<div class="article-date"><span class="article-date">{{ post.date }}</span></div>
<div class="article-post>"><span class="article-content"> {{ post.content }} </span></div>
</div>
</div>
</div>
</div>
</div>
Having trouble where I went wrong. I strongly suspect that it's some small typo or something with my SPA location/locationProvider in app.js but it looks the same in my other apps, unless my eyes are fooling me (which could be totally happening!)
What I did for a fix was simply this:
changed the listing view's anchor:
<h3 class="article-title"><a target="_self" data-ng-href="/post/{{post.title}}"> {{ post.title }} </a></h3>
to include the /blog# portion in the href so that I have:
<h3 class="article-title"><a target="_self" data-ng-href="/blog#/post/{{post.title}}"> {{ post.title }} </a></h3>
Simple fix, cause only the blog portion or webpage of my website is the angularJS, everything else is not so the routing was not being called to route it until it saw /blog# as part of the app.

AngularJS controller, template and routing issue

I am having a few issues getting my head around why this is not working:
template
<div>
<ul>
<li ng-repeat="x in get">
{{ x.name }}
</li>
</ul>
</div>
controller
angular.module('app')
.controller('SubstancesCtrl', function ($scope) {
$scope.get = [{name: "LOL"}];
});
routes
angular.module('app')
.config(function ($routeProvider) {
$routeProvider
.when('/', { controller: 'PostsCtrl', templateUrl: '/templates/posts.html' })
.when('/register', { controller: 'RegisterCtrl', templateUrl: '/templates/register.html' })
.when('/login', { controller: 'LoginCtrl', templateUrl: '/templates/login.html' })
.when('/substances', { controller: 'SubstancesCtrl', templateUrl: '/templates/substances.html'})
});
index.html
<!DOCTYPE html>
<html ng-app='app'>
<head>
<link rel='stylesheet' href='http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css'>
<link rel='stylesheet' href='/app.css'>
</head>
<body ng-controller='ApplicationCtrl'>
<nav class='navbar navbar-default'>
<div class='container'>
<ul class='nav navbar-nav'>
<li><a href='/#/'>Posts</a></li>
<li><a href='/#/register'>Register</a></li>
<li><a href='/#/login'>Login</a></li>
<li>Substances</li>
</ul>
<p ng-if='currentUser' class='navbar-text navbar-right'>
Signed in as {{currentUser.username}}
</p>
</div>
</nav>
<div class='container' ng-view></div>
<script src='http://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-rc.4/angular.js'></script>
<script src='http://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-rc.4/angular-route.js'></script>
<script src='/app.js'></script>
</body>
</html>
I can see that the template is being replaced by the ng-view directive however the get variable is not being treated in the manner i thought it would: i thought i would get one list item node with the value of LOL
You angular module has not been created, You should declare your module in app.js. As you are using angular routing you need to include its module in your app module.
angular.module('app',['ngRoute'])
Also you need to update your Angular to stable versions 1.4.4 is stable one, because you are using 1.3.0-rc.4 in which rc stands for release candidate which is pre-release version, which may have bug in most of the cases. Thats why I told you to go for stable version of AngularJS. You could also use close stable version which is 1.3.14
Additionally your template has <li ng-repeat="x in get()"> but get function is not defined in the scope, resultant would be nothing would be render on the UI.
angular.module('app')
.controller('SubstancesCtrl', function ($scope) {
$scope.lol = "LOL";
$scope.get = function(){
//write a code here which will return list
//so that ng-repeat will loop through the list
//& will show that data on HTML
//something like below
return {"name": "LOL"}; //in real case there must be something different object to return.
}
});
Alexis King was quite correct in that there were 3 very embarrassing issues with the code, it should have looked like this ( -_- )
template
<div>
<ul>
<li ng-repeat="x in get">
{{ x.name }}
</li>
</ul>
</div>
controller
angular.module('app')
.controller('SubstancesCtrl', function ($scope) {
$scope.get = [{name: "LOL"}];
});
routes were exactly the same.
The biggest issue however was in my gulp script which failed to pick up changes in these new files, I have rewrote the build script to ensure all files from the directories containing these files now are watched and all changes are reflected in the browser.
My excuse: need more coffee.

AngularJS routing not working after adding second state

I am using the ui.router. First when I just set the home state everything was working fine. But after adding the articles state my routing wouldn't work. I have following angular code:
var app = angular.module('ibrahimsBlog', ['ui.router'])
app.config([
'$stateProvider',
'$urlRouterProvider',
function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('home', {
url: '/home',
templateUrl: '/home.html',
controller: 'PrimaryController'
});
.state('articles', {
url: '/articles/{id}',
templateUrl: '/articles.html',
controller: 'ArticlesController'
});
$urlRouterProvider.otherwise('home');
}])
app.factory('articlesFactory', [function(){
var art = { articles: [] };
return art;
}])
app.controller('ArticlesController', [
'$scope',
'$stateParams',
'articlesFactory',
function($scope, $stateParams, articlesFactory){
$scope.article = articlesFactory.articles[$stateParams.id];
}]);
app.controller('PrimaryController', [
// Two Way Data Binding ist nur möglich mit scope Variablen.
'$scope',
'articlesFactory',
function($scope, articlesFactory) {
$scope.articles = articlesFactory.articles;
$scope.articles = [
{ title : 'foo', content : "foo", likes : 5, date : '12/15/2014' },
{ title : 'bar', content : "bar", likes : 2, date : '12/14/2014' },
{ title : 'baz', content : "baz", likes : 4, date : '12/23/2014' }
];
$scope.addArticle = function() {
if(!$scope.title || $scope.title === '') { return; }
$scope.articles.push(
{
title: $scope.title,
content: $scope.content,
likes: 0,
date: '12/15/2014',
comments: [
{ author: 'foo', comment: 'bar', upvotes: 0 }
]
}
);
$scope.title = '';
$scope.content = '';
}
$scope.likeArticle = function(article) {
article.likes += 1;
}
}]);
And here is my html file:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Ibrahims Blog</title>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>
<script src="app.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.10/angular-ui-router.js"></script>
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet">
<style> .glyphicon-heart { cursor:pointer } </style>
</head>
<body ng-app="ibrahimsBlog">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<ui-view></ui-view>
<form ng-submit="addArticle()" style="margin-top:30px;">
<h3>Create a new article!</h3>
<div class=form-group">
<input type="text"
placeholder="title"
ng-model="title">
</input>
</div>
<div class="form-group">
<input type="text"
placeholder="content"
ng-model="content">
</input>
</div>
<button type="submit" class="btn btn-primary">Hinzufügen</button>
</form>
<script type="text/ng-template" id="/home.html">
<div class="page-header">
<h1>Ibrahims Blog</h1>
</div>
<span>
Go
</span>
</script>
<script type=text/ng-template" id="/articles.html">
<div class="page-header">
<h3> {{ article.title }} </h3>
</div>
<div ng-repeat="article in articles">
<span class="glyphicon glyphicon-heart"
ng-click="likeArticle(article)"></span>
{{ article.title }} - "{{ article.content }}" - Likes: {{ article.likes }}, Date: {{ article.date }}
</div>
</script>
</div>
</div>
</body>
</html>
Unfortunately everything I receive is following part of the html
<form ng-submit="addArticle()" style="margin-top:30px;">
<h3>Create a new article!</h3>
<div class=form-group">
<input type="text"
placeholder="title"
ng-model="title">
</input>
</div>
<div class="form-group">
<input type="text"
placeholder="content"
ng-model="content">
</input>
</div>
<button type="submit" class="btn btn-primary">Hinzufügen</button>
</form>
Edit
Unfortunately there is still a part which is not working.. When I use the Go button, I see the change of the URL, but it then instant redirects me to the home template. On the server I get a 404 Error. Do you know why this is happening?
I think you have a semi-colon in the wrong place when defining the $stateProvider. You aren't chaining the .state calls properly because the first semi-colon terminates the statement:
$stateProvider
.state('home', {
url: '/home',
templateUrl: '/home.html',
controller: 'PrimaryController'
}); // <-------------------------Remove this semi-colon!
.state('articles', {
url: '/articles/{id}',
templateUrl: '/articles.html',
controller: 'ArticlesController'
});
Like chubbsondubs stated, I had to remove a semicolon. But since that was just a cause for one problem here is the other fault I found later on. In my template in this line
<script type=text/ng-template" id="/articles.html">
The quotation marks were missing! That was the reason for the 404. It should be like this:
<script type="text/ng-template" id="/articles.html">

Views or Routing do not work in Angular tutorial

I found angular tutorial, super simple, but it does not work. nothing happens when it should change the views. Here is the code:
This is the main index.html
<!DOCTYPE html>
<html data-ng-app="demoApp">
<head>
<title></title>
<script src="Scripts2/angular.min.js"></script>
</head>
<body >
<div >
<div data-ng-view=""></div>
</div>
<script>
var demoApp = angular.module('demoApp', []);
demoApp.config(['$routeProvider', function ($routeProvider){
$routeProvider
.when('/view1',
{
controller: 'SimpleController',
templateUrl: 'Partials/View1.html'
})
.when('/view2',
{
controller: 'SimpleController',
templateUrl: 'Partials/View2.html'
})
.otherwise({ redirectTo: '/view1' });
}]);
var controllers = {};
controllers.SimpleController = function($scope){
$scope.customers =[
{name:'John', city:'Phoenix'},
{name:'Jane', city:'Frisco'},
{name:'Susan', city:'New York'}
];
$scope.addCustomer = function(){
$scope.customers.push({ name: $scope.newCustomer.name, city: $scope.newCustomer.city});
}
};
demoApp.controller(controllers);
</script>
And these are 2 views:
view1.html:
<div class="container" >
<h1>View1</h1><br/>
Name: <input type="text" data-ng-model="filter.name" />
<br/>
<ul>
<li data-ng-repeat="cust in customers | filter: filter.name | orderBy: 'city'"> {{cust.name | uppercase}} - {{cust.city | lowercase}} </li>
</ul>
<br/>
Customer Name </br>
<input type="text" data-ng-model="newCustomer.name"/>
<br/>
Customer City </br>
<input type="text" data-ng-model="newCustomer.city"/>
<br/>
<button data-ng-click="addCustomer()" value="Create" />
<br/>
<a href="#/view2" >Go to View2</a>
</div>
and view2.html
<div class="container" >
<h1>View2</h1><br/>
City: <input type="text" data-ng-model="city" />
<br/>
<ul>
<li data-ng-repeat="cust in customers | filter: city | orderBy: 'city'"> {{cust.name | uppercase}} - {{cust.city | lowercase}} </li>
</ul>
</div>
It seems you've found a tutorial based on a older version of Angular. ngRoute has been seperated into it's own module in the later versions.
You therefore need to specify a dependency in your app:
var demoApp = angular.module('demoApp', ['ngRoute']);
And you need to download and load the script after your angular-library:
<script src="Scripts2/angular.min.js"></script>
<script src="Scripts2/angular-route.min.js"></script>
I think this should do the trick.
Update: And make sure you run your code via a webserver, and not just statically from a folder on your machine, or else you will get a "Cross origin requests are only supported for HTTP" error. http://plnkr.co/edit/ is good for testing stuff. Just choose new -> AngularJS
Update 2: Link to plunker testing this: http://plnkr.co/edit/IxbB1zbo7fg9He7mJ97k?p=preview

Resources