AngularJS 1.3 Routing not working; Controller never called - javascript

I can't for the life of me get AngularJS to work properly. I am not messing with templates or anything of that nature yet, I'm just trying to get the call to the controller to work correctly.
Here is a portion of my homepage.html
<div class="row" ng-app="eventsApp">
<div class="column small-12 content">
<p>Temporary Test.</p>
<div ng-view></div>
<ul class="small-block-grid-2 medium-block-grid-4 large-block-grid-5 shots">
<li>
<div class="thumb">
<a href="#Testing">
<div class="ctr-show s1">
<div class="show"><i class="fa fa-search-plus fa-lg"></i></div>
</div>
<img src="/img/screenshots/thumbs/g" alt="">
</a>
</div>
</li>
...
Here is my app.js
'use strict';
var eventsApp = angular.module('eventsApp', [
'ngRoute',
'ngSanitize',
]);
alert("testing number 1");
eventsApp.config(['$routeProvider', function($routeProvider){
$routeProvider.
when('/Testing', {
templateUrl : 'Views/AngularViews/temp.html',
controller : 'TestingController'
});
}]);
Later on in the app.js....
eventsApp.controller('TestingController',
function($scope) {
alert("testing number 2");
});
Can anyone spot what I'm doing incorrectly? It just isn't working at all. The first alert pops up just fine, the second one never pops up, even after using the correct route.
Thanks in advance.

This is my code in coffeescript that works, I cannot spot any error in your implementation (and since there is no error on console...)
App.config [
'$provide'
'$routeProvider'
($provide, $routeProvider) ->
$routeProvider
.when('/testing', {
templateUrl: 'test.hml'
controller : 'TestingController'
})
]
iDsign.App.controller('TestingController', ($scope)->
alert('something')
)

Related

AngularJS UI Router: ui-sref not updating URL in address bar?

I'm building an AngularJS app and I'm using UI-Router in order to navigate through the app.
The flow of the web app consist in first registering or login, then it takes you to a main grid that has a lot of elements that are being displayed through ng-repeat and when you click in one of them it takes you to a dashboard that displays information of the element that has been clicked and it also successfully changes the path to index.html#!/dashboard/(here goes the name of the element)
This is the html 5 code of that main grid:
<div class="container">
<div class="row" ng-controller="ribtStateServicesController" >
<div class="col-md-3 ribt_HomeGrid" ng-repeat="estado in estados" >
<div class="img-ribt_overlay" >
<a ng-click="doWork(estado.idState)" ui-sref="dashboard({ribtNameState: estado.idState})">
<img src="{{estado.image}}" class="img-thumbnail">
<div class="ribt_overlay" ></div>
</a>
</div>
</div>
</div>
</div>
However, in that same dashboard I have a side menu, that has the same elements that were used in the main grid before. So I figured that it would take the same logic to be able to use the params that the UI-Router offer in order to change the URL and the content displayed. But it does nothing.
This is the code in the HTML of the dashboard's side menu:
<div class="col-md-6 nopadding" ng-repeat="estado in estados | filter:busqueda">
<md-card md-ink-ripple="#ffffff">
<img ng-src="{{estado.nolabel}}" class="md-card-image ribt_estado_side_img"
ui-sref="dashboard({ribtNameState: estado.idState})"
alt="Estado" ng-click="doWork(estado.idState); toggleLeft()">
<md-card-title class="nopadding">
<md-card-title-text>
<p class="ribt_card_estado_nombre">{{estado.nombre}}</p>
</md-card-title-text>
<md-menu>
<md-button class="md-icon-button float-right" aria-label="Share" ng-click="$mdMenu.open()">
<i class="material-icons">more_vert</i>
</md-button>
<md-menu-content width="4" ng-mouseleave="$mdMenu.close()">
<md-menu-item ng-repeat="item in [1, 2, 3]">
<md-button>
Option {{item}}
</md-button>
</md-menu-item>
</md-menu-content>
</md-menu>
</md-card-title>
</md-card>
</div>
Heres is the code in my app config:
ribtApp.config(function ($stateProvider,$mdThemingProvider,$locationProvider) {
$stateProvider
.state('login', {
url: '',
templateUrl: 'ribtComponents/ribtLogin/ribtLogin.html',
controller: 'ribtLoginController'
})
.state('home', {
url: '/home',
templateUrl: 'ribtComponents/ribtHome/ribtHome.html',
controller: 'ribtStateServicesController'
})
.state('dashboard', {
url: '/dashboard/{ribtNameState}',
templateUrl: 'ribtComponents/ribtDashboard/ribtDashboard.html',
controller: 'ribtStateServicesController',
resolve:{
ribtNameState: ['$stateParams', function($stateParams){
return $stateParams.ribtNameState;
console.log($stateParams.ribtNameState)
}]
}
});
I tried a console log to see if the param was being changed and it is but it does nothing to the URL path. I've tried a lot of code that I've found in stackoverflow but none of them has worked. I would be deeply thankful if you could help me with this.
You need to switch your ng-hrefs to ui-srefs, which is what ui-router uses to set up links to change states. So something like...
<div class="col-md-6 nopadding" ng-repeat="estado in estados | filter:busqueda">
[...]
<a ng-click="doWork(estado.idState)" ng-href="index.html#!/dashboard/{{estado.idState}}">
should be something more like...
<div class="col-md-6 nopadding" ng-repeat="estado in estados | filter:busqueda">
[...]
<a ng-click="doWork(estado.idState)" ui-sref="dashboard({ribtNameState: estado.idOrWhatever})">
with the caveat that I don't know what doWork is actually doing, so I don't know if that is necessary.
If you need to transition in a controller, you can also inject $state and use $state.go(...), but most of the time ui-srefs can get it handled in my experience.

Load view on button click with Angularjs in single page application

I am very new to AngularJS. This is my first project so please forgive me if my question is very basic.
I am created a page using simple HTML and put three button on it.
On these button click I want to load views in the lowel part of screen.
Index.html
<body ng-app="MyApp">
<div class="tab" ng-controller="TabControlController">
<button class="tablinks" onclick="openTab(event, 'Environments')" ng-click="Views/EnvironmentsView.html">Environments</button>
<button class="tablinks" onclick="openTab(event, 'SIT_Downloader')" ng-click="Views/SITDownloaderView.html">Download PCP Client</button>
<button class="tablinks" onclick="openTab(event, 'Users')">PCP Users</button>
</div>
<div id="Environments" class="tabcontent" ng-controller="environmentController">
<div>
<div ng-view></div>
</div>
</div>
<div id="SIT_Downloader" class="tabcontent" ng-controller="SITDownloaderController">
<div>
<div ng-view></div>
</div>
</div>
<div id="Users" class="tabcontent">
<div>
<div ng-view></div>
</div>
</div>
</body>
Bootstrap.js
var MyApp= angular.module('MyApp', ['ngRoute'])
.config(function($routeProvider) {
$routeProvider
.when('/',
{
templateUrl: 'Views/EnvironmentsView.html',
controller: window.environmentController
})
.otherwise({ redirectTo: '/' });
});
views are very simple as of now...
<h3>PCP Users</h3>
<p>This screen will be used to add/remove users</p>
Can anyone help me to understand what I am missing here or redirect me to some page with full example of this.
This is single page application.
You can try instead of calling a function onclick of a button ,just link the route with anchor tag
Maintain the routes in separate js file
like:
(function() {
'use strict';
angular.module('app.home').config(appRoutes);
appRoutes.$inject = ['$routeProvider', '$locationProvider'];
function appRoutes($routeProvider, $locationProvider) {
$routeProvider
.when('/', {
templateUrl: '../yourhtmlfile.html',
controller: 'controllerName',
resolve: {}
})
}
})();
Also you dont need to have multiple ng-view for each view
have a single ng-view
<div>
<div ng-view></div>
</div>
this helps in loading the html page when you click on the tag and loads the corresponding html file.
You have some problem in your sample.
1- change <button ng-click=".." ></button> to
you can use button also but you should crate a function that changes the current route to new route.
<button ng-click="changeRoute('/home')" >Home</button>
$scope.changeRoute = function(newRoute){
$location.path(newRoute);
}
2- wrong syntax for define controller in route.(put controller in each route)
3- Don't need to multiple ng-view
Demo

Angularjs nested controller called just one time

I'm new in Angularjs and I have an app, with some "projects", which have a local menu displayed on some pages. Index.html contains the main navbar with footer :
<body ng-app="ysi-app" ng-controller="MainController">
<div class="page-content">
<div class="row">
<div class="col-md-2">
<div class="sidebar content-box" style="display: block;">
<ul class="nav">
<!-- Main menu -->
<li ng-if="isAuthenticated()">{{name}}</li>
<li class="current">Dashboard</li>
<li>Projects</li>
</ul>
</div>
<div ng-if="isAuthenticated() && displayProjectMenu == true" ng-include="'views/localMenu.html'" ng-controller="LocalMenuController">
</div>
</div>
<div ng-view></div>
</div>
So I have a nested controller LocalMenuController for the local menu and a main controller. The project controller sets the datas :
angular.module('ProjectCtrl',[]).controller('ProjectController',function($scope,$location, ProjectService,$route, AuthenticationService, $rootScope){
$scope.setProjectDatas = function(projectName, projectId){
ProjectService.setName(projectName);
$rootScope.projectId = projectId;
};});
I set the id of one project to the $rootScope for testing (I have a Service which will do that better) and get it in the LocalMenuController :
angular.module('LocalMenuCtrl',[]).controller('LocalMenuController', function($scope, ProjectService, $rootScope) {
$scope.projectId = '';
$scope.projectId = $rootScope.projectId;
});
I display projects in a table and when I clicked on one of it, the function setProjectDatas(name,id) is called. The problem is when I clicked on one project, the id of the project is correct and set but when I go previous and clicked on another project, the id is the old id of the project previously clicked. The datas are not updating. I googled my problem but found nothing on it.
I think the LocalMenuController is called only one time but not after.
What am I doing wrong ?
Thank you
UPDATE
I've created a Directive which displays the template but it's still not updating the partial view localMenu.
LocalMenu Directive :
angular.module('LocalMenuCtrl',[]).controller('LocalMenuController', function($scope, ProjectService, $rootScope) {
console.log('-> LocalMenu controller');
})
.directive('localMenu', function($rootScope){
return {
templateUrl: '/YSI-Dev/public/views/partials/localMenu.html',
link: function(scope){
scope.projectId = $rootScope.projectId;
}
};
});
A part of index.html
<div ng-if="isAuthenticated() && displayProjectMenu == true" ng-controller="LocalMenuController">
<div local-menu></div>
</div>
Partial view localMenu :
<div class="sidebar content-box" style="display: block;">
<ul class="nav">
<li><i class="glyphicon glyphicon-list-alt"></i> Backlog</li>
<li><i class="glyphicon glyphicon-user"></i> My team </li>
</ul>
</div>
I'm trying to get the projectId from the $rootScope and inject it in the <a href="#/project/{{projectId}}" but I have some troubles. What's the way to do that ?
First of all, try using directives instead of ng-controller. You can encapsulate your code and template into a unit. You can also try creating a component. Pass some data to the directive/component and Angular will take care of updating the template and running whatever needs to run within the directive/component. (Given that you used two-way data-bindings)
From the code above, I cannot see what would trigger LocalMenuController to run again.

AngularJs controller not getting called when a link is clicked

Currently, I'm working on an initial AngularJs app for an Admin Console for a database. I'm pretty new at Angular, so I've started off by modifying the phonecat tutorial. Basically, I've got a Jersey REST API that I need to make calls against in Angular. CORS is not the problem, they're both running on the same Tomcat.
The data structure is Projects have Groups within them.
I can redirect from Login to the Projects list page, the controller for getting the list of projects is called, and I can click a project and get the details page and its controller is called. But when I click a link from the project-details page and have it redirect to the groups-list page, the REST api call is never made (according to Chrome's network monitor.)
I'm rather confused because hypothetically it should be the exact same as the projects list.
Controllers:
phonecatControllers.controller('ProjectListCtrl', ['$scope', '$http',function($scope, $http){
$http.get('http://localhost:8080/WrappingServer/rest/api/project?show_hidden=true').success(function(data){
$scope.projects = data.hits.hits
});
$scope.orderprop='timeModified';
}]);
phonecatControllers.controller('GroupListCtrl', ['$scope', '$http',function($scope, $http){
$http.get('http://localhost:8080/WrappingServer/rest/api/group?projectID='+$scope.project._id+'&show_hidden=true').success(function(data){
$scope.groups = data.hits.hits //Yes this is correct. It's an elasticsearch cluster.
});
$scope.orderprop='timeModified';
}]);
phonecatControllers.controller('ProjectDetailCtrl', ['$scope', '$routeParams' ,'$http', function($scope, $routeParams, $http){
$http.get('http://localhost:8080/WrappingServer/rest/api/project/'+$routeParams.projectId).success(function(data){
$scope.project=data;
});
}]);
project-details.html:
<img ng-src="{{project._source.imageUrl}}" class="project">
<h1>{{project._source.name}}</h1>
<p>{{project._id}}</p>
<ul class="specs">
<a ng-href="#/groups" ng-click=>Group IDs</a>
<dd ng-repeat="group in project._source.groupIDs">{{proj._source.name}}
{{group.groupID}}
</dd>
</ul>
group-list.html
<div class="container-fluid">
<div class="row">
<div class="col-md-2">
<!--Sidebar content-->
Search: <input ng-model="query">
Sort by:
<select ng-model="orderprop">
<option value="name">Alphabetical</option>
<option value="dateModified">Newest</option>
</select>
</div>
<div class="col-md-10">
<!--Body content-->
<ul class='groups'>
<li ng-repeat="group in groups | filter:query | orderBy:orderprop" class="thumbnail">
<img ng-src=" {{group._source.imageUrl}}" alt="{{group._source.name}}">
{{group._source.name}}
<p>{{group._source.timeModified}}</p>
</li>
</ul>
</div>
</div>
</div>
app.js
'use strict';
/* App Module */
var phonecatApp= angular.module('phonecatApp', [
'ngRoute', 'phonecatControllers', 'phonecatFilters']
);
phonecatApp.config(['$routeProvider',
function($routeProvider){
$routeProvider.when('/projects',
{
templateUrl: 'partials/project-list.html',
controller: 'ProjectListCtrl'
}).when('/projects/:projectId', {
templateUrl: 'partials/project-detail.html',
controller: 'ProjectDetailCtrl'
}).when('/home', {
templateUrl: 'partials/login.html',
controller: 'LoginCtrl'
}).when('/groups',
{
templateUrl: 'partials/group-list.html',
controller: 'GroupListCtrl'
})
.otherwise({
redirectTo: '/home'
});
}]);
I've even tried to take an approach where the projectID is a routeParam (kind of like for Project details), but still no luck.
Let me know if you anything else to answer my question. I know it's going to be something so stupidly simple that a handprint will appear on my forehead. (From what I've seen, possibly a space where it's not supposed to be.)
Thanks!
<a href="#/groups/{{group._id}}" class="thumb"> should be <a ng-href="/groups/{{group._id}}" class="thumb">
Also <a ng-href="#/groups" ng-click=>Group IDs</a should not have an empty ngClick on it. It should look like <a ng-href="/groups">.
So basically just change the attribute of the link from href to ng-href and then remove the # symbol from the link.
You have:
phonecatControllers.controller('GroupListCtrl', ['$scope', '$http',function($scope, $http){
$http.get('http://localhost:8080/WrappingServer/rest/api/group?projectID='+$scope.project._id+'&show_hidden=true').success(function(data){
$scope.groups = data.hits.hits //Yes this is correct. It's an elasticsearch cluster.
});
$scope.orderprop='timeModified';
}]);
I would instead do this in your controller:
phonecatControllers.controller('GroupListCtrl', ['$scope', '$http',function($scope, $http) {
$scope.function_name = function() {
$http.get('http://localhost:8080/WrappingServer/rest/api/group?projectID='+$scope.project._id+'&show_hidden=true').success(function(data){
$scope.groups = data.hits.hits //Yes this is correct. It's an elasticsearch cluster.
});
}
$scope.orderprop='timeModified';
}]);
For your link that is within the HTML element possessed by the controller,
<a ng-href="/groups" ng-click="function_name()">Group IDs</a>
As it is, your AJAX call is just sitting there. You need to place it within a block where code is executed for it to be called, just like in any other case. In this case, you must place it within a function that serves as a callback tied to ng-click.

Scope variable not updating in view despite $scope.$digest

.controller('PizzaCtrl', ['$scope','$state','$ionicLoading',
function($scope, $state, $ionicLoading) {
$scope.$emit('menu-refresh-request');
$scope.$on('menu-refresh-response', function(event) {
console.log("pizza");
$scope.$broadcast('scroll.refreshComplete');
$scope.items = $scope.$parent.menu.pizze;
console.log($scope.items[1].price);
$ionicLoading.hide();
});
$scope.doRefresh = function() {
$scope.$emit('menu-refresh-request');
};
}])
The data all checks out. The correct item information is logged to the console. However, the ng-repeat="item in items" directive in my view does not update with the pizza items.
I tried using $scope.$apply and $scope.$digest inside the event listener, but the console threw an error saying the digest was already in progress.
Also worth noting that this controller has two sibling controllers that have identical logic to this one, except for different sections of the menu. The console.log("pizza") statement isn't executed until I click into the state.
Is there a clear reason why my view is not updating?
<ion-refresher pulling-text="Updating Menu..." on-refresh="doRefresh()">
<div class="list menu-list">
<a class="item menu-item" ng-repeat="item in items" ui-sref="menu.pizza-detail({ index: $index })">
<div class="row">
<h3 class="row" ng-bind="item.name"></h3>
<div class="row">
<div class="list-price col col-15">
<h4 class="list-value" ng-bind="item.price"></h4>
</div>
<div class="list-description col col-85">
<p ng-bind="item.description"></p>
</div>
</div>
</div>
</a>
</div>
Instead of using $scope.$apply try to use $timeout angular service.
The $timeout does not generate error like „$digest already in progress“ because $timeout tells Angular that after the current cycle, there is a timeout waiting and this way it ensures that there will not any collisions between digest cycles and thus output of $timeout will execute on a new $digest cycle.
.controller('PizzaCtrl', ['$scope','$state','$ionicLoading', '$timeout'
function($scope, $state, $ionicLoading, $timeout) {
$scope.$emit('menu-refresh-request');
$scope.$on('menu-refresh-response', function(event) {
console.log("pizza");
$scope.$broadcast('scroll.refreshComplete');
$timeout(function(){
$scope.items = $scope.$parent.menu.pizze;
});
console.log($scope.items[1].price);
$ionicLoading.hide();
});
$scope.doRefresh = function() {
$scope.$emit('menu-refresh-request');
};
}])
Turns out the solution to this problem is that I needed to add a missing closing tag to the <ion-refresher> tag.
<ion-refresher pulling-text="Updating Menu..." on-refresh="doRefresh()"></ion-refresher>
<div class="list menu-list">
<a class="item menu-item" ng-repeat="item in items" ui-sref="menu.pizza-detail({ index: $index })">
<div class="row">
<h3 class="row" ng-bind="item.name"></h3>
<div class="row">
<div class="list-price col col-15">
<h4 class="list-value" ng-bind="item.price"></h4>
</div>
<div class="list-description col col-85">
<p ng-bind="item.description"></p>
</div>
</div>
</div>
</a>
</div>

Categories