Infinite loops inside of angular controller - javascript

When I open up my app in a window, I get stuck in an infinite loop where angular keeps calling the GameCtrl and freezes the window. Here's the code:
index.html
<!DOCTYPE html>
<html ng-app="baseball">
<head>
<script src="/js/vendor/angular.min.js"></script>
<script src="/js/vendor/d3.v3.min.js"></script>
<script src="/js/baseball.js"></script>
</head>
<body>
<div ng-view></div>
</body>
</html>
baseball.js
var app = angular.module('baseball', []);
function GameCtrl ($scope) {
}
app.config(function ($routeProvider) {
$routeProvider
.when('/', {
controller: GameCtrl,
})
.otherwise({redirectTo:'/'});
});
I feel like this should be trivial; any help would be much appreciated.
Edit
Even with the templateUrl, it still goes into an infinite loop. Here's the updated config and the template code:
baseball.js
app.config(function ($routeProvider) {
$routeProvider
.when('/', {
controller: GameCtrl,
templateUrl: '/templates/field.html'
})
.otherwise({redirectTo:'/'});
});
templates/field.html
<div>hi</div>

Add the content you want to display here <div ng-view></div>
in your route
$routeProvider
.when('/', {
controller: GameCtrl,
templateUrl: path/to/your_content.html
})

You need to include angular-route.js in the head
and then inject 'ngRoute' into your module.
See http://docs.angularjs.org/api/ngRoute and http://docs.angularjs.org/api/ngRoute.$routeProvider

Related

Hashbang defaulting in angular application

Do the newest versions of angular/angular-route 1.6.1 use hashbang by default? Take this piece of code for example, I have to use #! when linking to partials because #/ or #/partial2 does not work. I thought that you'd have to set a hash prefix but it looks like it's defaulting to that behavior:
<!DOCTYPE html>
<html ng-app='myApp'>
<head>
<title></title>
<script src="bower_components/angular/angular.min.js"></script>
<script src="bower_components/angular-route/angular-route.js"</script>
<script>
var myApp = angular.module('myApp', ['ngRoute']);
myApp.config(function ($routeProvider) {
$routeProvider
.when('/',{
templateUrl: 'partials/view1.html',
})
.when('/partial2',{
templateUrl: 'partials/view2.html'
})
.otherwise({
redirectTo: '/'
});
});
myApp.controller('view1Controller', function ($scope) {
$scope.sports = ['golf', 'basketball', 'hockey', 'tennis', 'football'];
});
myApp.controller('view2Controller', function ($scope) {
$scope.message = 'We are using another controller';
});
</script>
</head>
<body>
<div ng-app='myApp'>
Partial 1 | Partial 2
<div ng-view="">
</div>
</div>
</body>
</html>
Starting angular 1.6.0, #!/ becomes defaults in routes. I basically worked down versions until #/ worked, which was 1.5.11.

Angular Routing not populating ng-view

I have an issue were my routing is not populating my view.
I have the following code running from an Xampp local server:
angular 1.4.9
index.html:
<html>
<head>
<script src="scripts/angular.js" type="javascript/text"></script>
<script src="scripts/Ng-Route.js" type="javascript/text"></script>
<script src="scripts/app.js" type="javascript/text"></script>
</head>
<body ng-app="myApp">
<div ng-view></div>
</body>
</html>
user.html:
<div>
<fieldset>
Hello, {{ctrl.message}}
</fieldset>
</div>
app.js:
var app = angular.module('myApp', ['ngRoute']);
app.config(function($routeProvider) {
$routeProvider
.when('/', {
templateUrl : 'user.html',
controller : 'controller as ctrl'
});
$routeProvider.otherwise({ redirectTo: '/' });
});
app.controller('controller', function() {
var self = this;
self.message = 'Everyone';
});
I have absolutely no clue why this is failing, nothing shows up on the page. I am expecting "Hello, Everyone".
Any help would appreciated.
You had mistaken declaring your controller on your route. controller does accept controller name in string/controller function. And use controllerAs option to alias your controller.
$routeProvider
.when('/', {
templateUrl : 'user.html',
controller : 'controller',
controllerAs: 'ctrl'
});

Angular states point to correct controller but not html

I am just setting up a simple Angular app as I've done countless times. I added a home state and a separate state for a note taking app, yet neither states are displaying/injecting the html partials into the ui-view. I think it might be an issue with my ui-router setup, but I cannot find the issue. I console log from my controllers and they trigger correctly, so the states are clearly pointing to the right controllers.
Index
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>title</title>
<script src="bower_components/angular/angular.js"></script>
<script src="node_modules/angular-ui-router/release/angular-ui-router.js"></script>
<script src="app.js"></script>
<script src="factory.js"></script>
<script src="config.js"></script>
</head>
<body ng-app="myApp">
<ui-view></ui-view>
</body>
</html>
config
app.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('home', {
url: '/home',
templateURL: './home.html',
controller: 'homeCtrl'
})
.state('list', {
url: '/list',
templateURL: '/list.html',
controller: 'listCtrl'
})
$urlRouterProvider.otherwise('/home');
});
app.js
'use strict';
var app = angular.module('myApp', ['ui.router']);
app.controller('listCtrl', function($scope, myFactory) {
console.log("list working!");
$scope.items = myFactory.items
$scope.addItem = function() {
$scope.items.unshift($scope.newItem);
$scope.newItem = "";
}
})
app.controller('homeCtrl', function($scope) {
console.log("home working!");
$scope.test = 'test'
})
My home state should load a partial containing:
<div>
<h1>Welcome!</h1>
</div>
Plunker
http://plnkr.co/edit/ngHYDtx0VBe2YPlBeJ3t?p=preview
It has to be
templateUrl: './home.html',
Also, it is not desirable to use relative paths for templates, './home.html' and 'home.html' will be cached internally as two different templates.

Angular UI-Router loading controller only when route is selected

Let's say I have two pages, cloud and settings. I have the following code set up:
var routerApp = angular.module('APP', ['ui.router']);
routerApp.config(function($stateProvider, $urlRouterProvider, $locationProvider) {
$locationProvider.html5Mode(true);
$urlRouterProvider.otherwise('/cloud');
$stateProvider
.state('cloud', {
url: '/cloud',
templateUrl: 'pages/templates/cloud.html',
controller: 'cloud',
})
.state('settings', {
url: '/settings',
templateUrl: 'pages/templates/settings.html',
controller: 'settings'
});
});
routerApp.controller('cloud', function($scope, $http, $state) {
alert("cloud");
});
routerApp.controller('settings', function($scope, $http, $state) {
alert("settings");
});
HTML
<!DOCTYPE html>
<html lang="en" ng-app="APP">
<head>
<title>TITLE</title>
<base href="/">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.13/angular-ui-router.min.js"></script>
<script src="/js/app.js" type="text/javascript"></script>
</head>
<body>
<div id="navContainer">
<a ui-sref="cloud">Cloud</a>
<a ui-sref="settings">Settings</a>
</div>
<div id="pageContent">
<div ui-view></div>
</div>
</body>
</html>
Regardless of what page I load, settings or cloud, the each controller will run no matter what. Meaning I will get 2 alerts, regardless, when I reload the page.
Could anyone help explain what I need to do so that if I reload my website on /settings, only the code in my settings controller will run and vice versa?
If you have your controllers declared in the partials(views) that your router is loading then those controllers will only fire when the view is loaded. It sounds to me like you need a parent controller(s) that will fire to give you logic that can controller both of the views.
Your Code:
$stateProvider.state('cloud', {
url: '/cloud',
templateUrl: 'pages/templates/cloud.html',
controller: 'cloud',
})
.state('settings', {
url: '/settings',
templateUrl: 'pages/templates/settings.html',
controller: 'settings'
});
You are setting the controllers there if you would like them to share a controller simply refer to the same controller like so:
$stateProvider
.state('cloud', {
url: '/cloud',
templateUrl: 'pages/templates/cloud.html',
controller: 'shared',
})
.state('settings', {
url: '/settings',
templateUrl: 'pages/templates/settings.html',
controller: 'shared'
});

ionic how to add blank page as home page of the app?

I would like to add new page into default ionic app with tabbed menu and display this page as the default page of the app.
Here is how I tried to do that:
I added new state into app.js
.state('home', {
url: '/home',
views: {
'home': {
templateUrl: 'templates/home.html',
controller: 'HomeCtrl'
}
}
})
and set default router to home page
$urlRouterProvider.otherwise('/home');
And template file:
<ion-view title="Home">
<ion-content class="padding">
<h1>Home page</h1>
</ion-content>
</ion-view>
Now, if I am trying to go to http://myapp.loc/index.html#/home I got always black page without content.
What I'm doing wrong?
Thanks for any help.
EDIT:
In order to Error: [ng:areq] Argument 'HomeCtrl' is not a function, got undefined
I'm adding related code.
Added controllers:
angular.module('starter.controllers', [])
.controller('HomeCtrl', function($scope, $location) {
})
.controller('DashCtrl', function($scope) {
})
.controller('FriendsCtrl', function($scope, Friends) {
$scope.friends = Friends.all();
})
.controller('FriendDetailCtrl', function($scope, $stateParams, Friends) {
$scope.friend = Friends.get($stateParams.friendId);
});
Order in index.html is following
<script src="js/app.js"></script>
<script src="js/controllers.js"></script>
<script src="js/controllers/overall_stats.js"></script>
<script src="js/services.js"></script>
I would say, that solution here should be surprisingly simple:
Remove the view name 'home'. In fact change it to '' (empty string)
There is a working plunker with this change?
.state('home', {
url: '/home',
views: {
// instead of this
// 'home': {
// use this
'': {
templateUrl: 'tpl.home.html',
controller: 'HomeCtrl',
}
}
})
Why? Because most likely the index.html would look like this:
<body ng-app="myApp" >
...
<ion-nav-view></ion-nav-view>
</body>
And that means that the view name is "", almost like <ion-nav-view name=""></ion-nav-view>
Check that in action here
EXTEND based on the question extension
if we use ionic-like approach with separated file and module for controllers:
// inside of the index.html
<script src="js/controllers.js"></script>
// the controller.js
angular.module('starter.controllers', [])
We must be sure, that our app.js does contain that module as well:
angular.module('myApp', [
'ionic',
'starter.controllers' // this is a MUST
])

Categories