angular.js modular controller "undefined" when using $routeParams - angularjs

the following returns an error in the console "ReferenceError: ThingCtrl is not defined"
var myApp = angular.module('myApp', []);
myApp.config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/things', {templateUrl: 'partial.html', controller: ThingCtrl}).
when('/things/:id', {templateUrl: 'detail.html', controller: ThingCtrl}).
otherwise({redirectTo: '/things'});
}]);
myApp.controller('ThingCtrl', ['$scope', '$routeParams', function($scope, $routeParams) {
$scope.thing = [
{
'title':'first thing',
'first':'one',
'second': 'two',
'third': 'three'
}
];
}]);
however it works fine when the controller is defined like:
function ThingCtrl($scope, $routeParams) {
$scope.thing = [
{
'title':'first thing',
'first':'one',
'second': 'two',
'third': 'three'
}
]
};
Why does it not work using the modular syntax?

I believe that the issue is here:
when('/things', {templateUrl: 'partial.html', controller: ThingCtrl})
This is telling Angular to point at the ThingCtrl object, which is undefined and causes an error.
Try enclosing the controller name in quotes like this:
when('/things', {templateUrl: 'partial.html', controller: 'ThingCtrl'})
This should allow Angular to properly use dependency injection.

Related

How to add new controller in angular.module like MyController

angular.module('myApp.view1', ['ngRoute'])
.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/view1', {
templateUrl: 'view1/view1.html',
controller: 'View1Ctrl'
});
}])
.controller('View1Ctrl', [function() {
}]);
In same you can append an component to you module
angular.module('myApp.view1', ['ngRoute'])
.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/view1', {
templateUrl: 'view1/view1.html',
controller: 'View1Ctrl'
});
$routeProvider.when('/view2', {
templateUrl: 'view1/view2.html',
controller: 'View2Ctrl'
});
}])
.controller('View1Ctrl', [$scope, function($scope) {
}])
.controller('View2Ctrl', [$scope, function($scope) {
}]);
Other way would be you can just store your module in some variable and do use that variable while appending angular component to angular.module
var app = angular.module('myApp.view1', ['ngRoute'])
app.config(['$routeProvider', function($routeProvider) {
//..code here
}])
app.controller('View1Ctrl', [$scope, function($scope) {
}])
app.controller('View2Ctrl', [$scope, function($scope) {
}]);
More preferred way would be to use IIFE pattern In that case there you wont store any global variable, As IIFE create a closer function that scope ends when function gets end
App.js
function(){
angular.module('myApp.view1', ['ngRoute'])
.config(['$routeProvider', function($routeProvider) {
//..code here..
}])
}();
View1Ctrl.js
function(){
angular.module('myApp.view1')
.controller('View1Ctrl', [function() {
}]);
}();
View2Ctrl.js
function(){
angular.module('myApp.view1')
.controller('View2Ctrl', [function() {
}]);
}();
I've added another controller declaration, and added it to $routeProvider, see the relevant developer guide page for more info
angular.module('view1', 'view2', ['ngRoute'])
.config(['$routeProvider', function($routeProvider) {
$routeProvider
.when('/view1', {
templateUrl: 'view1/view1.html',
controller: 'View1Ctrl'
})
.when('/view2', {
templateUrl: 'view2/view2.html',
controller: 'myController'
})
}])
.controller('View1Ctrl', [function() {
}]);
.controller('myController', [function() {
}]);
note that appending multiple controllers into a single file is not a recommended practice

angular sub module route

I have a:
main module : kp
sub module : kp.venue
I want kp.venue to have it's own "route" definitions (for all paths relative to that module).
This is what I am trying to achieve in the code bellow.
Can anyone explain me why it doesn't work?
I followed the technique presented in this post: https://stackoverflow.com/a/15301427/971008
(function () {
'use strict';
angular.module('kp.venue', [])
.config(['$routeProvider',
function($routeProvider) {
$routeProvider
.when("/venue", {
template : "<p>This is the venue module</p>",
controller: "VenueCtrl"
});
}
])
.controller('VenueCtrl', ['$scope',
function($scope){
console.log("VenueController");
}
]);
angular.module('kp', ['ngRoute', 'ngAnimate', 'kp.venue'])
.config(['$locationProvider', '$routeProvider',
function($locationProvider, $routeProvider) {
$locationProvider.html5Mode({enabled:true, requireBase:false});
$routeProvider
.when("/", {
template: "<p>main app</p>",
controller: "MainController"
})
.otherwise({
redirectTo: '/'
});
}
]);
//Load controller
angular.module('kp')
.controller('MainController', ['$scope',
function($scope) {
$scope.test = "Testing...";
}
]);
}());
Note that I have already tried to move "kp.venue" bellow the definition of "kp" module to be sure that it was not a problem related to things not being loaded in the right order.

Angularjs Use injectect module's controller in route definition

I'm new to angular and I'm trying to modularlize my app.
My main module gets some other module and I want to use the controller of the injected module in my route definition.
Some simple example would be very helpful!
This does not work:
var app = angular.module('Contacting_App', ['LeadLookup']);
app.config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/main',
{controller: 'MainCtrl',
templateUrl: 'apex/f42_Contacting_Main'}
).
when('/lead',
{module: 'LeadLookup',
controller: 'LeadLkpCtrl',
templateUrl: 'apex/f42_Lead_Lookup'}
).
otherwise(
{redirectTo: '/main'}
);
}]);
This tutorial page may point you in the correct direction docs.angularjs.org/tutorial/step_07
The main things you should look at are:
Module
var phonecatApp = angular.module('phonecatApp', [
'ngRoute',
'phonecatControllers'
]);
routeProvider
phonecatApp.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/phones', {
templateUrl: 'partials/phone-list.html',
controller: 'PhoneListCtrl'
}).
when('/phones/:phoneId', {
templateUrl: 'partials/phone-detail.html',
controller: 'PhoneDetailCtrl'
}).
otherwise({
redirectTo: '/phones'
});
}]);
Controllers
var phonecatControllers = angular.module('phonecatControllers', []);
phonecatControllers.controller('PhoneListCtrl', ['$scope', '$http',
function ($scope, $http) {
$http.get('phones/phones.json').success(function(data) {
$scope.phones = data;
});
$scope.orderProp = 'age';
}]);
phonecatControllers.controller('PhoneDetailCtrl', ['$scope', '$routeParams',
function($scope, $routeParams) {
$scope.phoneId = $routeParams.phoneId;
}]);

angularjs $stateParams returns a function (?!?)

I have a very simple AngularJs app.
Here my app.js file:
angular.module('myApp', [
'ngRoute',
'ngResource',
'ui.bootstrap',
'ui.router',
'myApp.controllers'
]).
config(['$stateProvider', function($stateProvider) {
$stateProvider.
state('home', {
url: "/{Id:[0-9]}",
templateUrl: 'html/home.html',
controller: 'HomeCtrl'
});
}]);
And my controllers.js file:
angular.module('myApp.controllers', []).
controller('HomeCtrl', ['$stateParams', function($stateParams) {
console.log($stateParams.Id);
}]);
The return of the console.log($stateParams.Id) is undefined. While I'm expecting "1" (my Id).
Otherwise if I ask for console.log($stateParams) it returns a function (?!?):
function l(a){function c(a){var b=r({},a,{data:Dc(a.data,a.headers,d.transformResponse)});return 200<=a.status&&
300>a.status?b:m.reject(b)}var d={method:"get",transformRequest:e.transformRequest,transformResponse:e.transformResponse},f=function(a){function b(a){var c;q(a,function(b,d){Q(b)&&(c=b(),null!=c?a[d]=c:delete a[d])})}var c=e.headers,d=r({},a.headers),f,g,c=r({},c.common,c[A(a.method)]);b(c);b(d);a:for(f in c){a=A(f);for(g in d)if(A(g)===a)continue a;d[f]=c[f]}return d}(a);r(d,a);d.headers=f;d.method=Ia(d.method);(a=Mb(d.url)?b.cookies()[d.xsrfCookieName||e.xsrfCookieName]:s)&&(f[d.xsrfHeaderName||
e.xsrfHeaderName]=a);var h=[function(a){f=a.headers;var b=Dc(a.data,Cc(f),a.transformRequest);w(a.data)&&q(f,function(a,b){"content-type"===A(b)&&delete f[b]});w(a.withCredentials)&&!w(e.withCredentials)&&(a.withCredentials=e.withCredentials);return u(a,b,f).then(c,c)},s],k=m.when(d);for(q(x,function(a){(a.request||a.requestError)&&h.unshift(a.request,a.requestError);(a.response||a.responseError)&&h.push(a.response,a.responseError)});h.length;){a=h.shift();var l=h.shift(),k=k.then(a,l)}k.success=
function(a){k.then(function(b){a(b.data,b.status,b.headers,d)});return k};k.error=function(a){k.then(null,function(b){a(b.data,b.status,b.headers,d)});return k};return k}
While I'm expecting {Id: "1"}.
What am I doing wrong???
Just to try I changed my state in the following way:
$stateProvider.
state('home', {
url: "/{Id:[0-9]}",
templateUrl: 'html/home.html',
controller: function($stateParams){
console.log($stateParams);
}
});
}]);
And it works! It returns {Id: "1"} but unfortunately this is not an option for me since what I described here is a small portion of a much bigger and complicated App (so I'd like to have app.js and controllers.js files).
Any suggestion?

Angularjs dependency injection in resolve

I would like to use proper dependency injection in MyCtrl1to inject the fields of the MyCtrl1.resolve object. I've tried many different combinations of attempting to inject #MyCtrl1.resolve etc. with no luck.
#MyCtrl1 = ($scope, $http, batman, title) ->
$scope.batman = batman.data
$scope.title = title.data
#MyCtrl1.resolve = {
batman: ($http) ->
$http.get('batman.json')
title: ($http) ->
$http.get('title.json')
}
##MyCtrl1.$inject = ['$scope', '$http'] -- commented out because not sure how to inject resolve fields
angular
.module( 'app', [])
.config( ['$routeProvider', '$locationProvider', ($routeProvider, $locationProvider)->
$locationProvider.html5Mode(true)
$routeProvider.when('/', {templateUrl: 'index.html', controller: MyCtrl1, resolve: MyCtrl1.resolve})
$routeProvider.otherwise({redirectTo: '/'})
])
angular.bootstrap(document,['app'])
Resolve is a property of a route and not a controller. Controllers would be injected with dependencies defined on a route level, there is no need to specify resolve properties on a controller.
Taking one of your examples (transformed to JavaScript), you would define your controller as always, that is:
MyCtrl1 = function($scope, $http, batman, title) {
$scope.batman = batman.data;
$scope.title = title.data;
}
and then the resolve property on a route:
angular.module('app', []).config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
$locationProvider.html5Mode(true)
$routeProvider.when('/',{templateUrl: 'index.html', controller: MyCtrl1, resolve: {
batman: ['$http', function($http) {
return $http.get(..).then(function(response){
return response.data;
});
}],
title: ['$http', function($http) {
return //as above
}]
}});
$routeProvider.otherwise({redirectTo: '/'});
}]);
If you want to minify the code using resolve section of routing you need to use array-style annotations - I've included this in the example above.

Resources