I'm a newbie in Angular, i whant to make use of $controllerProvider, i see an example like my code, but the attribute register got undefined:
var appTmw = angular.module('appTmw', ['ui.router']);
appTmw.config(function($stateProvider, $urlRouterProvider, $controllerProvider) {
appTmw.register = {
controller: $controllerProvider.register
};
})
and here, a register of controller, the register attribute got undefined:
appTmw.register.controller('CustomersController', ['$scope', 'config', 'dataService',
function ($scope, config, dataService) {
//Controller code goes here
}]);
what a problem with the code?
controllerProvider is the $controller service used by Angular to create new controllers:
https://docs.angularjs.org/api/ng/provider/$controllerProvider
If you are new to angular I suggest you to use the standard way to create a controller:
var appTmw = angular.module('appTmw', ['ui.router']);
appTmw.controller('controllerName', function($scope){
//your code for the controller here
});
I hope it helps.
Related
I'm new using Angular with MVC Web Api but using VB instead of C#. I'm trying to make an SPA web site and I have some week trying to solve this problem.
In my app.js I defined the routing to my views and the controllers I'm going to use in them
var goMessage = angular.module('goMessage', ['ngRoute', 'goMessage.controllers', 'goMessage.services', 'goMessage.directives']);
angular.module('goMessage.controllers', []);
angular.module('goMessage.services', []);
angular.module('goMessage.directives', []);
goMessage.config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
//Vista Login
$routeProvider.when('/login/inicio', {
controller: 'loginController',
controllerAs: 'lgCtrl',
templateUrl: 'Home/Login'
});
//Vista Usuarios
$routeProvider.when('/usuarios/lista', {
controller: 'usuariosController',
controllerAs: 'usCtrl',
templateUrl: 'Home/Usuarios'
});
$routeProvider.when('/dashboard/inicio', {
controller: 'dashboardController',
controllerAs: 'dashCtrl',
templateUrl: 'Home/Dashboard'
});
$locationProvider.html5Mode(true);
}]);
The usuariosController.js controller is working very well, its code is:
angular.module('goMessage.controllers')
.controller("usuariosController", ['$scope', '$http', 'ws', '$window', '$timeout', '$route',
function ($scope, $http, ws, $window, $timeout, $route) {
//DeclaraciĆ³n de variables
var me = this;
//Ordenamiento por default
this.ordenarPorColumna = 'UsuarioID';
this.reverse = false;
// More code...
}
]);
And the loginController.js controller code is:
angular.module('goMessage.controllers')
.controller('loginController', ['$scope', '$http', 'ws', '$window', '$timeout', '$route',
function ($scope, $http, ws, $window, $timeout, $route) {
//DeclaraciĆ³n de variables
var me = this;
this.myData = "Data$$$";
}
]);
In the Login.vbhtml view I'm following the same pattern as the Usuarios.vbhtml view. I define my ng-app in the _layout.vbhtml and I don't define any controller inside any view.
The error I'm unable to solve is this:
Error Image
Look at the AngularJs Expression
As you can see, I've defined both controller using the same way but the only one that works is the usuarios one and any other controller I add doesn't work.
Here I show you the scripts loading order:
Scripts Loading Order
I'm using my local IIS and working in VS2012.
The angular JS version is 1.6.
To register the logic modules as controller, filter and etc..., you need to add this code in your app.config
var app = angular.module("App", []);
var config = function ($controllerProvider, $compileProvider, $filterProvider, $provide) {
app.controller = $controllerProvider.register;
app.directive = $compileProvider.register;
app.filter = $filterProvider.register;
app.factory = $provide.factory;
app.service = $provide.service;
app.constant = $provide.constant;
//your codes
}
config.$inject = ["$controllerProvider", "$compileProvider", "$filterProvider", "$provide"];
app.config(config);
Why this happen?
sometimes we don't need to add all of controllers in our main index which has ng-view or ui-view for that we should put our controller as lazyload to the app.config as you do this in your config, because of that the main app for get the controllers need to register controllers and other modules.
This issue might happen due to asynchronous loading of scripts. The script order might also be an issue. You can add a console.log at the beginning of loginController to check whether the component is loaded correctly.
if I have the following angularjs code route provider how can I pass through a dependency into the blaCtrl controller please?
Many thanks,
app.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/bla', { templateUrl: 'bla.html', controller: 'blaCtrl' });
trying to get something like
'use strict';
app.controller('blaCtrl', function ($scope) {
$scope.mydata = ['111', '222', '333']; // how can I change this to be a method call to a dependency, i.e.
$scope.mydata = mydependency.getData(); // example what I need
});
update
My app file looks like this - I'm still not getting the data displayed?
'use strict';
var app = angular.module('myApp', ['ngRoute']);
app.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/application', { templateUrl: 'partials/application.html', controller: 'myCtrl' });
$routeProvider.otherwise({ redirectTo: '/application' });
}]);
controller
'use strict';
app.controller('myCtrl', 'myService', function ($scope, myService) {
debugger; // doesn't get hit?
$scope.stuff = myService.getStuff();
});
console error
- I get this error in the console Error: [ng:areq] http://errors.angularjs.org/1.4.5/ng/areq?p0=applicationCtrl&p1=not%20a%20function%2C%20got%20string
There are 3 ways of dependency annotation according to angular docs.
Inline Array Annotation
In this case your controller defenition should look like:
'use strict';
app.controller('blaCtrl', ['$scope', 'mydependency', function ($scope, mydependency) {
$scope.mydata = mydependency.getData();
}]);
$inject Property Annotation
'use strict';
var blaCtrl = function ($scope, mydependency) {
$scope.mydata = mydependency.getData();
};
blaCtrl.$inject = ['$scope', 'mydependency'];
app.controller('blaCtrl', blaCtrl);
Implicit Annotation
This one you used in your example code to inject $scope variable. Not recommended, minificattion will broke such code.
'use strict';
app.controller('blaCtrl', function ($scope, mydependency) {
$scope.mydata = mydependency.getData();
});
The fact that you reference your controller not in HTML but in routeProvider doesn't make any difference.
You can pass a dependency to the controller from within the controller. You're injecting the $scope dependency already, and you can inject others like $location and $rootScope if you'd like.
I am very beginner in Angular.js, I am using the Ui-router framework for routing.
I can make it work upto where I have no parameters in the url. But now I am trying to build a detailed view of a product for which I need to pass the product id into the url.
I did it by reading the tutorials and followed all the methods. In the tutorial they used resolve to fetch the data and then load the controller but I just need to send in the parameters into the controllers directly and then fetch the data from there. My code looks like below. when I try to access the $stateParams inside the controller it is empty. I am not even sure about whether the controller is called or not.
The code looks like below.
(function(){
"use strict";
var app = angular.module("productManagement",
["common.services","ui.router"]);
app.config(["$stateProvider","$urlRouterProvider",function($stateProvider,$urlRouterProvider)
{
//default
$urlRouterProvider.otherwise("/");
$stateProvider
//home
.state("home",{
url:"/",
templateUrl:"app/welcome.html"
})
//products
.state("productList",{
url:"/products",
templateUrl:"app/products/productListView.html",
controller:"ProductController as vm"
})
//Edit product
.state('ProductEdit',{
url:"/products/edit/:productId",
templateUrl:"app/products/productEdit.html",
controller:"ProductEditController as vm"
})
//product details
.state('ProductDetails',{
url:"/products/:productId",
templateUrl:"app/products/productDetailView.html",
Controller:"ProductDetailController as vm"
})
}]
);
}());
this is how my app.js looks like. I am having trouble on the last state, ProdcutDetails.
here is my ProductDetailController.
(function(){
"use strict";
angular
.module("ProductManagement")
.controller("ProductDetailController",
["ProductResource",$stateParams,ProductDetailsController]);
function ProductDetailsController(ProductResource,$stateParams)
{
var productId = $stateParams.productId;
var ref = $this;
ProductResource.get({productId: productId},function(data)
{
console.log(data);
});
}
}());
NOTE : I found lot of people have the same issue here https://github.com/angular-ui/ui-router/issues/136, I can't understand the solutions posted their because I am in a very beginning stage. Any explanation would be very helpful.
I created working plunker here
There is state configuration
$urlRouterProvider.otherwise('/home');
// States
$stateProvider
//home
.state("home",{
url:"/",
templateUrl:"app/welcome.html"
})
//products
.state("productList",{
url:"/products",
templateUrl:"app/products/productListView.html",
controller:"ProductController as vm"
})
//Edit product
.state('ProductEdit',{
url:"/products/edit/:productId",
templateUrl:"app/products/productEdit.html",
controller:"ProductEditController as vm"
})
//product details
.state('ProductDetails',{
url:"/products/:productId",
templateUrl:"app/products/productDetailView.html",
controller:"ProductDetailController as vm"
})
There is a definition of above used features
.factory('ProductResource', function() {return {} ;})
.controller('ProductController', ['$scope', function($scope){
$scope.Title = "Hello from list";
}])
.controller('ProductEditController', ['$scope', function($scope){
$scope.Title = "Hello from edit";
}])
.run(['$rootScope', '$state', '$stateParams',
function ($rootScope, $state, $stateParams) {
$rootScope.$state = $state;
$rootScope.$stateParams = $stateParams;
}])
.controller('ProductDetailController', ProductDetailsController)
function ProductDetailsController ($scope, ProductResource, $stateParams)
{
$scope.Title = "Hello from detail";
var productId = $stateParams.productId;
//var ref = $this;
console.log(productId);
//ProductResource.get({productId: productId},function(data) { });
return this;
}
ProductDetailsController.$inject = ['$scope', 'ProductResource', '$stateParams'];
Check it here
But do you know what is the real issue? Just one line in fact, was the trouble maker. Check the original state def:
.state('ProductDetails',{
...
Controller:"ProductDetailController as vm"
})
And in fact, the only important change was
.state('ProductDetails',{
...
controller:"ProductDetailController as vm"
})
I.e. controller instead of Controller (capital C at the begining)
The params in controller definition array should be strings
["ProductResource", "$stateParams"...
This should properly help IoC to inject the $stateParams
And even better:
// the info for IoC
// the style which you will use with TypeScript === angular 2.0
ProductDetailsController.$inject = ["ProductResource", "$stateParams"];
// this will just map controller to its name, parmas are defined above
.controller("ProductDetailController", ProductDetailsController);
I'm just about to write tests for my angularjs-app. However when Im trying to run the test which is very simpel one i get the following error.
Error: [ng:areq] Argument 'MyPageController' is not a function, got undefined
I'll provide code for the setup of my controllers, config etc.
Route
var myPageApp = angular.module('myPageApp', ['ngRoute', 'ngAnimate', 'ngSanitize', 'app.controller', 'app.service', 'app.filter', 'app.config'])
.config(['$routeProvider', function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'App_AngularJs/partials/myPage/myPage.htm',
controller: 'MyPageController',
reloadOnSearch: false,
});
}]);
Controller
var myPageApp = angular.module('app.controller', ['oci.treeview', 'ui.bootstrap'])
.controller('MyPageController', ['$scope', '$routeParams', '$location', '$timeout', '$filter', '$modal', 'myPageService',
function ($scope, $routeParams, $location, $timeout, $filter, $modal, myPageService) {
init();
function init() {
$scope.page = { value: $routeParams.page || 1 };
}
}]);
Simpel test
'use strict';
describe('Testing MyPageController', function(){
var scope;
//mock Application to allow us to inject our own dependencies
beforeEach(angular.mock.module('myPageApp'));
//mock the controller for the same reason and include $rootScope and $controller
beforeEach(angular.mock.inject(function($rootScope, $controller){
//create an empty scope
scope = $rootScope.$new();
//declare the controller and inject our empty scope
$controller('MyPageController', { $scope: scope });
}));
// tests start here
it('should map routes to controllers', function () {
module('myPageApp');
inject(function ($route) {
expect($route.routes['/'].controller).toBe('MyPageController');
expect($route.routes['/'].templateUrl).
toEqual('App_AngularJs/partials/myPage/myPage.htm');
});
});
it('should have variable assigned = "1"', function(){
expect(scope.page.value).toBe(1);
});
});
My wildest and best guess is that i need to mock app.controller but how? Everything starts out with myPageApp which holds references to service, controller etc etc..
I think your issue is that routing and the controller are trying to load different modules viz "myPageApp" and "app.controller" and in your test with beforeEach you are trying to load 'myPageApp' module to which router is associated but not the controller.
So it seems to me that either you use same module for both router and controllers. Or try loading both modules in the test. Still I believe associating the router and controller with same module makes more sense.
An small example as below. Extract the application module in common js file (may be call it app.js)
var myApp = angular.module(
'myApp');
Now define router as
myApp.config(function ($routeProvider) {
$routeProvider
.when('/testUrl', {
templateUrl: '/myApp/views/test-view',
controller: 'TestViewController'
})
Similary define controller as
myApp.controller('TestViewController',[your dependencies goes here])
And now in your tests
beforeEach(module('myApp'));
This will work for sure. Hope it helps.
Angular Experts,
I am new to Angular Js and trying to update input in one controller with value from the input in another controller. I am not sure whether it is even possible or not?
I have created js fiddle link just to give an idea.
http://jsfiddle.net/MwK4T/
In this example when you enter a value in controller 2's input, and click 'Set Value it does update biding with <li></li> but does't not update input of the controller 1.
Thanks in advance
I made it working using $broadcast. And it is working like a charm.
I did something like this.
App.controller('Ctrl1', function($rootScope, $scope) {
$rootScope.$broadcast('msgid', msg);
});
App.controller('Ctrl2', function($scope) {
$scope.$on('msgid', function(event, msg) {
console.log(msg);
});
});
Thanks for helping me out.
Best way would be to use the service, we need to avoid the event as much we can, see this
var app= angular.module('testmodule', []);
app.controller('QuestionsStatusController1',
['$rootScope', '$scope', 'myservice',
function ($rootScope, $scope, myservice) {
$scope.myservice = myservice;
}]);
app.controller('QuestionsStatusController2',
['$rootScope', '$scope', 'myservice',
function ($rootScope, $scope, myservice) {
$scope.myservice = myservice;
}]);
app.service('myservice', function() {
this.xxx = "yyy";
});
Check the working example