Controller for views in a state - angularjs

I'm trying to define a controller within an abstract state so that I can have a single controller for all my views but the functions inside controller are not getting called if the controller is defined outside.
.state('update', {
url : '/update',
abstract: true,
template: '<ui-view/>',
controller : function($scope) { //works
$scope.hello = function() {
alert("hello");
}
}
controller : 'updateController' // Doesn't work
})
.state('update.detail', {
url : '/view/:id',
views : {
"" : {
templateUrl : 'update-detail.html'
},
"header#update.detail" : {
templateUrl : 'header.html'
},
"genericnavigation#update.detail" : {
templateUrl : 'generic-navigation.html'
},
"mnavigation#update.detail" : {
templateUrl : 'mobile-navigation.html'
},
"updatecontent#update.detail" : {
templateUrl : 'update-content.html'
}
}
})
HTML
header.html
<div ng-click="hello();"></div> //Click event doesn't get fired for ( controller : 'updateController' )
app.controller('updateController', ['$scope', '$state', function($state, $scope) {
console.log("inside update")
$scope.hello = function() {
alert("hello");
}
}]);

Look how you defined your controller:
['$scope', '$state', function($state, $scope)
The arguments are not in the right order. So the $state variable is in fact the scope, and the $scope variable is in fact the state.

Related

Angular modal service doesn't recognize the templateUrl

https://github.com/dwmkerr/angular-modal-service
When I want to show the modal, the console show this error
GET http://localhost:3000/copy/duplicate_view.html 404 (Not Found)
on the controller:
(function() {
'use strict';
function editCtrl($scope, appSettings,pricingService, ModalService) {
$scope.show = function() {
ModalService.showModal({
templateUrl: '../copy/duplicate_view.html',
controller: "DialogDemoCtrl"
})
};
}
angular.module('myApp')
.controller('editCtrl', editCtrl)
;
})();
On the HTML:
<a class="btn-green-alt btn" href ng-click="show()">{{'dialog.EXPORT' | translate}}</a>
at Dependency
angular
.module('myApp', [
'daterangepicker',
'angular-loading-bar',
'ui.tinymce',
'angularModalService'
])
And this is what i see on the service's code...
var getTemplate = function getTemplate(template, templateUrl) {
var deferred = $q.defer();
if (template) {
deferred.resolve(template);
} else if (templateUrl) {
$templateRequest(templateUrl, true).then(function (template) {
deferred.resolve(template);
}, function (error) {
deferred.reject(error);
});
} else {
deferred.reject("No template or templateUrl has been specified.");
}
return deferred.promise;
};
Set absolute path to your template whitout using ..
EDIT
Based on your comment about the project structure
app
specifications
copy
duplicate_view.html
Then set templateUrl as follow
templateUrl: 'app/specifications/copy/duplicate_view.html',

How to pass stateParams to the angular controller?

I try to define stateParams in the controller, but it returns me an empty object {}
My app.js:
angular.module('testApp', ['ui.router','ngResource'])
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('app', {
url:'/',
views: {
'header': {
templateUrl : 'views/header.html'
},
'messages': {
templateUrl : 'views/messages.html',
controller : 'MessageController'
},
'chat': {
templateUrl : 'views/chat.html',
controller : 'ChatController'
},
'footer': {
templateUrl : 'views/footer.html'
}
}
})
.state('app.chat', {
url: ':id'
});
$urlRouterProvider.otherwise('/');
})
My controller.js:
angular.module('testApp')
.controller('IndexController', ['$scope', '$stateParams', function($scope,$stateParams) {
$scope.chosenMessage = $stateParams;
}]);
And my template:
<div ui-view="messages" class="col-xs-6"></div>
<div ui-view="chat" class="col-xs-6"></div>
I need an id from StateParams to define choosen message and chat content for the message.
The solution:
I have defined $state instead of $stateParams, and check for $state.params.id to get current state.

Passing variable name in angular route

Currently I am able to add routing mechanism in AngularJs with the following code :
App.config(function($routeProvider, $locationProvider) {
$routeProvider
.when('/', {
templateUrl : '/templates/home.html',
controller : 'landing'
})
.when('/login', {
templateUrl : '/templates/login.html',
controller : 'login'
});
});
What I need is an url in the format like /app/:appname which should fetch template called /template/:appname.html. I know that the appname can be accessed from controller using :
$routeParams.appname;
But how can I render template based on that parameter ?
You could do this:
App.config(function($routeProvider, $locationProvider) {
$routeProvider
.when('/app/:appname', {
templateUrl : '/templates/app-template.html',
controller : 'AppCtrl',
resolve: {
appPath: function ($route) {
return $route.current.params.appname;
}
}
})
});
in AppCtrl,
App.controller('AppCtrl', AppCtrl);
AppCtrl.$inject = [
'$scope'
'appPath'
];
function AppCtrl($scope, appPath) {
$scope.template = appPath + '.html';
}
in app-template.html, use ng-include as such
<div ng-include src="template"></div>
Hope this helps.
templateUrl can be use as function which returns a url.
App.config(function($routeProvider, $locationProvider) {
$routeProvider
.when('/', {
templateUrl : '/templates/home.html',
controller : 'landing'
})
.when('/:appname',{
templateUrl: function(params){
return "templates/"+params.appname +".html"
},
controller: 'Ctrl'
});
});

karma + jasmine + angular + ui router - unit test for a state with parent property

I have an angular module, lets say, moduleA. I am using angular ui-router to define the states.
moduleA has state stateA with resolve.
$stateProvider
.state('stateA', {
abstract: true,
parent: 'secure',
templateUrl: baseUrl + '/templates/root.html',
controller: 'rootCtrl',
resolve: {
value1: [ 'StateService', function ( StateService) {
return StateService.getValue1();
}],
value2: ['Service2', function(Service2) {
return Service2.getValue2();
}]
}
})
Then, I have another module "moduleB" in which I define state stateB with parent property stateA.
$stateProvider
.state('stateB', {
parent: 'stateA',
abstract: true,
templateUrl : baseUrl+'/templates/stateB.html'
})
.state('stateB.details', {
url: '/stateB/details/:param1/:param2',
resolve : {
value3 : ['$localStorage', '$stateParams', function($localStorage, $stateParams){
return $localStorage.value3[$stateParams.param1];
}]
},
views : {
'view1' : {
templateUrl : baseUrl+'/templates/view1.html',
controller: 'View1Ctrl'
},
'view2' : {
templateUrl : baseUrl+'/templates/view2.html',
controller : 'View2Ctrl'
}
}
})
In my Karma - Jasmine unit test for moduleB, I have
beforeEach(inject(function($rootScope, $state, $injector, $httpBackend) {
rootScope = $rootScope;
state = $state;
injector = $injector;
httpBackend = $httpBackend;
}));
it('should be an abstract state', function(){
var s = state.get('stateB');
expect(s.abstract).toBeTruthy();
});
Test fails with error TypeError: 'null' is not an object (evaluating 's.abstract')
If I comment the line parent: 'stateA', from stateB's definition, test will pass with success.
Can anyone help me?
Fixed. I was loading "moduleB" in my tests but not moduleA. I fixed my issue by loading "moduleA" in my tests. I had to add beforeEach(module('moduleA'));

dynamic configuration of states using ui-router

I am using ui-router to generate multiple states, views and subviews. it looks like below :
$stateProvider.state('dashboard', {
url : "/dashboard",
controller : function($scope, $filter) {
console.log($scope, '$scope');*/
views : {
"header":{
templateUrl : getTemplate("dashboardHeader"),
controller : function($scope, $filter) {
console.log($scope.location, '$scope');
}
},
"body" : {
templateUrl : getTemplate("dashboardChart"),
controller : function($scope, $filter) {
console.log($scope, '$scope');
}
}
}
}).state('dashboard.insight', {
url : "/:insight",
templateUrl : getTemplate("insight"),
controller : function($scope, $filter) {
console.log($scope, 'Sameer Test');
}
}).state('products', {
url : "/products",
views: {
"header":{
templateUrl: getTemplate("productHeader"),
controller: function($scope, Restangular, $filter, PlatformService){
.......
}
},
"body":{
templateUrl:getTemplate("products"),
controller : function($scope, Restangular, $filter, $route, $routeParams, $location, ngDialog,PlatformService) {
.......
} );
}
}
}
})
here dashboard and products are main views. insight is dynamically binded using ui-sref. i want to move all these a JSON structure so that i can configure which client needs which all states views and controllers. like some may need dashboard some may not.
So i decided to use app.run() to load these configurations. But i am not getting subviews of dashboard and states which are "dashboard.insight" (/:insight). As JSON will have dashboard not dashboard.insight.
How to achieve this.

Resources