Related
I'm using angularJS and when I'm injecting a Factory I get error:
app.js :
angular.module('myapp', [])
myfactory.js :
angular.module('myapp', [])
.factory('httpService', function($http, $timeout) {
});
Controller: test.js :
angular.module('myapp', [])
.controller('test', function($scope, $timeout, $sce, $http, httpService) {
$scope.submit = function() {
}
});
When I add httpService I get error. Everything seems to be right, I even use this factory in all projects. Error:
angular.min.js:92 Error: [$injector:unpr] http://errors.angularjs.org/1.2.25/$injector/unpr?p0=httpServiceProvider%20%3C-%20httpService
at Error (native)
at http://localhost:81/chah/assets/js/angularjs/angular.min.js:6:450
at http://localhost:81/chah/assets/js/angularjs/angular.min.js:36:202
at Object.c [as get] (http://localhost:81/chah/assets/js/angularjs/angular.min.js:34:305)
at http://localhost:81/chah/assets/js/angularjs/angular.min.js:36:270
at c (http://localhost:81/chah/assets/js/angularjs/angular.min.js:34:305)
at d (http://localhost:81/chah/assets/js/angularjs/angular.min.js:35:6)
at Object.instantiate (http://localhost:81/chah/assets/js/angularjs/angular.min.js:35:165)
at http://localhost:81/chah/assets/js/angularjs/angular.min.js:67:419
at http://localhost:81/chah/assets/js/angularjs/angular.min.js:54:25
Check the link in your error (https://docs.angularjs.org/error/$injector/unpr?p0=httpServiceProvider%20%3C-%20httpService):
You create module multiple times:
angular.module('myapp', [])
You should do it once. Then use without []
angular.module('myapp').factory ...
angular.module('myapp').controller ...
The reason for the error is because in the creation of the httpService and the controller you have used the setter i.e. angular.module('myapp', []) syntax for the module and not the getter syntax. angular.module('myapp').
Angular requires us to define a module only once, thus the subsequent redefining causes the error.
So in app.js, define the module:
angular.module('myapp', []) ;
In myfactory.js use the getter Syntax by removing the , []:
angular.module('myapp')
.factory('httpService', function($http, $timeout) {
});
And in test.js:
angular.module('myapp')
.controller('test', function($scope, $timeout, $sce, $http, httpService) {
$scope.submit = function() {
}
});
Here is a link to the docs
yes,
what you are doing is re-creating your app
what you need to do is define it once and continue using that instance
var app = angular.module('myapp', []);
app.factory('httpService', function($http, $timeout) {
});
app.controller('test', function($scope, $timeout, $sce, $http, httpService) {
$scope.submit = function() {
}
});
or if you want to retrieve your app the syntax is angular.module('myapp')
this returns 'myapp', but adding [], tells angular to create an app and not fetch it
Code should look like below:
angular.module('myapp', [])
.factory('httpService', function($http, $timeout) {
});
.controller('test', function($scope, $timeout, $sce, $http, httpService) {
$scope.submit = function() {
}
});
I'm new to Angular and cannot pinpoint where I am going wrong. I'm just trying to simply inject my factory into my controller, reference said: "Cannot read property 'validar' of undefined". I have two files, ServiceUtil.js where have a service and CentroCustoCtrl.js where I'm trying to use service's function.
The function at ServiceUtil.js:
(function () {
'use strict';
angular.module('Services', [])
.service('ValidarFormulario', [function () {
this.validar = function (form) {
var valido = true;
//code
}
return valido;
}
}]);
})();
And CentroCustoCtrl.js
(function () {
'use strict';
var app = angular.module("start", ['AxelSoft', 'ngLocalize',
'ngLocalize.Config', 'mvComponentes','Services'])
.value('localeConf', {
basePath: '../Scripts/Locales', ...
...
});
app.controller('CentroCustoCtrl', ['$scope', '$http', 'ValidarFormulario', function ($scope, $http, $rootScope, $timeout, ValidarFormulario) {
$scope.Salvar = function () {
if (ValidarFormulario.validar(document.getElementsByTagName('input'))) { ...// Cannot read property 'validar' of undefined
);
I tried with factory , but not worked too:
angular.module('Services', [])
.factory('ValidarFormulario', [function () {
return{
validar : function (form) {
var valido = true;
//code
}
}
return valido;
}
}
}]);
})();
Please, I appreciate any help you can provide.
The problem is you had wrong dependency sequence inside DI inline array, basically they are mismatching in number and their sequences
app.controller('CentroCustoCtrl', ['$scope', '$http', 'ValidarFormulario',
//removed $rootScope, $timeout which wasn't used.
function ($scope, $http, ValidarFormulario) {
OR either way you could just add the dependency inside array, if they are really gonna used inside controller like below
app.controller('CentroCustoCtrl', ['$scope','$http','$rootScope','$timeout','ValidarFormulario',
function ($scope, $http, $rootScope, $timeout, ValidarFormulario) {
Just change the below line of code
app.controller('CentroCustoCtrl', ['$scope', '$http', 'ValidarFormulario', function ($scope, $http, $rootScope, $timeout, ValidarFormulario) {
to
app.controller('CentroCustoCtrl', ['$scope', '$http', '$rootScope', '$timeout', 'ValidarFormulario', function ($scope, $http, $rootScope, $timeout, ValidarFormulario) {
This should work.
Well, also I've saw that your controller injections are wrong. You have:
App.controller('CentroCustoCtrl', ['$scope', '$http', 'ValidarFormulario', function ($scope, $http, $rootScope, $timeout, ValidarFormulario)
And you should have:
app.controller('CentroCustoCtrl', ['$scope', '$http', '$rootScope', '$timeout', 'ValidarFormulario', function ($scope, $http, $rootScope,$timeout, ValidarFormulario)
Injectors on "[ ]" must mach with function parameters.
When you set a module the syntax is:
angular.module('Services', [ here injections ])
But when you get a module to use it, syntax must be:
angular.module('Services')
I couldn't pass the parameter from angular controller to factory. Can any one help me on this? It works without passing parameter but when I pass it it's not.
var app = angular.module('employee', ['ui.grid', 'ui.grid.saveState', 'ui.grid.selection', 'ui.grid.cellNav', 'ui.grid.resizeColumns', 'ui.grid.moveColumns', 'ui.grid.pinning', 'ui.bootstrap', 'ui.grid.autoResize','ui.grid.pagination']);
app.controller('EmpCtrl', ['$scope', '$http', '$interval', '$modal', '$log', 'gridService', function ($scope, $http, $interval, $modal, $log, gridService) {
$scope.LoadNextPage = gridService.LoadNextPage("5");
}]);
var gridService = function ($http, $rootScope) {
return {
LoadNextPage: function (hh) {
alert(hh);
},
gridOptions:gridOptions
};
};
app.factory('gridService', ['$http', '$rootScope', gridService]);
And this is how I use it in the view
<span id="pcNext"
class="glyphicon glyphicon-step-forward"
ng-click="LoadNextPage()">
</span>
The problem is in your controller:
$scope.LoadNextPage = gridService.LoadNextPage("5");
This means that your LoadNextPage is not a function but rather a result of the call to a function in your service. Which btw doesn't return anything but rather just displays an alert. But in your view, you're using LoadNextPage as a function call...
Change it to this so your controller's LoadNextPage will be a function that you can call from the view.
$scope.LoadNextPage = gridService.LoadNextPage;
and in your view:
<span id="pcNext"
class="glyphicon glyphicon-step-forward"
ng-click="LoadNextPage(5)">
</span>
This should work.
Note: I suspect that your gridOptions are defined somewhere outside of scope of your code that you provided in the question so that it doesn't throw and error because of the missing (likely) object. So I considered this a typo in your code and not the actual problem.
Don't want params in your view?
No problem. You can either create a wrapper function or bind it to specific parameters in your code:
// wrap
$scope.LoadNextPage = function() {
return gridService.LoadNextPage("5");
};
// bind
$scope.LoadNextPage = gridService.LoadNextPage.bind(this, 5);
Or bake the number in your service...
Issue here is gridOptions:gridOptions is not defined which throws error.
Remove ,gridOptions:gridOptions from factory.
Check snippet for working code and compare with your code.
var app = angular.module('employee', []);
app.controller('EmpCtrl', ['$scope', 'gridService', function ($scope, gridService) {
$scope.clickMe = function() {
$scope.LoadNextPage = gridService.LoadNextPage("5");
}
}]);
var gridService = function() {
return {
LoadNextPage: function (hh) {
alert(hh);
}
};
};
app.factory('gridService', ['$http', '$rootScope', gridService]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="employee" ng-controller="EmpCtrl">
<button ng-click="clickMe()">Button</button>
</div>
you not defined gridOptions function see this link:
angular.module("myApp", []).controller("myCon", function($scope, $interval, gridService){
$scope.LoadNextPage = gridService.LoadNextPage("5");
}).factory('gridService', ['$http', '$rootScope', gridService]);
function gridService($http, $rootScope){
return {
LoadNextPage: function (hh) {
alert(hh);
}
};
}
see this link
Im trying to use a factory in angularJS, but I don't work as expected.
Here is my controller:
as.controller('Test', ['testFactory', function($scope, $http, $rootScope)
{
$http.get($rootScope.appUrl + '/nao/test/test')
.success(function(data, status, headers, config) {
$scope.test = data;
});
$scope.form = {};
$scope.submitForm = function(isValid) {
if(isValid)
{
testFactory.testFactoryMethod(function($http) {
$scope.test = data;
});
}
};
}]);
As you can see, I "include" my factory to the controller.
Here is my factory:
.factory('testFactory', function($http) {
return {
testFactoryMethod: function(callback) {
return $http('http://127.0.0.1:81/test/test', data).success(function(data) { callback(data);
});
}
};
});
When I run this, I get this error message:
Error: $http is undefined
#http://127.0.0.1:82/nao/js/controllers.js:82:3
Anyone who can help me?
This happens because of Angular $injector. When you provide an array as 2nd argument for .controller, the $injector tries to find all dependencies listed on it by their name and then inject them to the array's last element (which must be a function), so in your case, this is what happens:
'testFactory' -> $scope
undefined -> $http
undefined -> $rootScope
Your code should be either like this:
as.controller('Test', ['$scope', '$http', '$rootScope', 'testFactory', function($scope, $http, $rootScope, testFactory)
{
// ...
... or like this:
as.controller('Test', function($scope, $http, $rootScope, testFactory)
{
// ...
Edit: As #sp00m stated, the second example should not be used if you are going to uglify (minify) your code, because the uglifier algorithm will replace those identifiers with something like:
function(a, b, c, d)
And then AngularJS will not be able to find those dependencies anymore, whereas the first example would look like this:
['$scope', '$http', '$rootScope', 'testFactory', function(a, b, c, d)
Which is valid, because you are explicitly telling Angular which dependencies it must inject.
There is a problem with the dependencies in your controller. The names you have as strings in the array don't match the arguments to your factory function.
This should work:
as.controller('Test', ['$scope', '$http', '$rootScope', 'testFactory', function($scope, $http, $rootScope, testFactory)
{
$http.get($rootScope.appUrl + '/nao/test/test')
.success(function(data, status, headers, config) {
$scope.test = data;
});
$scope.form = {};
$scope.submitForm = function(isValid) {
if(isValid)
{
testFactory.testFactoryMethod(function($http) {
$scope.test = data;
});
}
};
}]);
I think you're forgetting the $http.post:
$http(url, data) should be $http.post(url, data)
And what others have said before, you need the testFactory injected in the controllers function.
You should declare your controller like this
as.controller('Test', ['$scope', '$http', '$rootScope', 'testFactory', function($scope, $http, $rootScope, testFactory)
{
....
}
I am trying to split a big controller. The way to go would be through factories, but since I am changing the DOM I should do it through controllers.
Then, what I am trying to achieve is to call a function defined in Cntrl2 from Cntrl1.
The example
html
<body ng-app="app">
<div ng-controller='Cntrl1'>
{{message}}
</div>
</body>
js
var myModule = angular.module('app', []);
angular.module('app').controller('Cntrl1',
['$scope', '$q', '$timeout', 'Share_scope',
function ($scope, $q, $timeout, Share_scope) {
Share_scope.process();
$scope.message = 'started';
}]);
angular.module('app').controller('Cntrl2',
['$scope', '$q', '$timeout', 'Share_scope',
function ($scope, $q, $timeout, Share_scope) {
Share_scope.x = function() {
alert('done');
}
}]);
angular.module('app').factory('Share_scope',
['$window', '$q',
function($window, $q) {
var x;
return {
process: function() {
return x;
},
};
}]);
The demo http://jsfiddle.net/T8rgv/7/
What I would expect is to define "var x" of the factory as the function of Cntrl2, and then execute this function through the factory when I call it from Cntrl1.
So, how to make this work? Is this approach correct? Or should I just change the DOM from a factory?
Cheers,
Gerard
Not knowing where in relation Cntrl2 is to Cntrl1, I would use emit or broadcast somewhat like this. Note from past experience I don't think it's a good idea to use two or more different modules in the same page.
var myModule = angular.module('app', []);
angular.module('app').controller('Cntrl1',
['$scope', '$q', '$timeout', 'myFactory',
function ($scope, $q, $timeout, myFactory) {
$scope.$emit('messageEvt','started');
myFactory.process().then(function() {
$scope.$emit('messageEvt','ended');
});
}]);
angular.module('app').controller('Cntrl2',
['$scope', '$q', '$timeout', $rootScope,
function ($scope, $q, $timeout, $rootScope) {
$rootScope.$on('messageEvt',function(e,msg) {
$scope.message = msg;
}
}]);
angular.module('app').factory('myFactory',
['$window', '$q','$timeout',
function($window, $q,$timeout) {
var x;
return {
process: function() {
var deferObj = $q.defer();
$timeout(function() {
deferObj.resolve(x);
});
return deferObj.promise;
},
};
}]);
I think better way to do this is by having factory maintain the model and both controllers updating it when needed.
I updated the fiddle to http://jsfiddle.net/hh5Cy/2/
angular.module('app').factory('Share_scope',
['$window', '$q',
function($window, $q) {
var x;
return {
getProcess: function() {
return x;
},
setProcess: function(value){
x = value;
}
};
}]);
Please let me know if I understood you wrongly.