Reputation: 1366
I have created an AngularJS factory in which I'm returning an object which has some functions as properties. My purpose is to call some function in another function from that returning using the this keyword but its giving an error. I tried to console.log the this keyword and I found out that, that this variable holds the scope of calling controller in which the factory is being injected. How can I tackle this kind of situation. this keyword should return the current returning object!
app.module('admin').factory('login', [function() {
return {
someFunc: function() {
return 'abc'
},
anotherFunc : function(){
var msg = this.someFunc();
return 'Msg is '+ msg;
},
yetAnotherFunc : function(){
var msg = this.someFunc();
return 'Msg is '+ msg;
}
}
}]).controller(['$scope', 'login', function($scope, login){
login.someFunc(); // Works Fine
login.anotherFunc(); // Error : this.someFunc is not a function
}])
Upvotes: 2
Views: 2298
Reputation: 31
https://jsfiddle.net/6fwu7ghs/
HTML
<div ng-app="test" ng-controller="testController">
<input type="button" ng-click="testFunc2()" value="test2" />
<input type="button" ng-click="testFunc1()" value="test1" />
</div>
JS
var testModule = angular.module('test',[ ]);
testModule.controller('common' , function( $scope ) {
$scope.testFunc1 = function(){
alert("test1");
};
});
testModule.controller('testController', function( $scope , $controller ){
//inherit
$controller('common', {
$scope: $scope
});
$scope.testFunc2 = function (){
alert("test2");
};
});
how about this way. I'm just using controller with 'inherit'
Do you really need to use 'Factory' ? then this is not an answer.
Upvotes: 0
Reputation: 5715
Try this:
app.module('admin').factory('login', [function() {
function someFunc() {
return 'abc';
}
return {
someFunc: someFunc,
anotherFunc : function(){
var msg = someFunc();
return 'Msg is '+ msg;
},
yetAnotherFunc : function(){
var msg = someFunc();
return 'Msg is '+ msg;
}
};
}]).controller(['$scope', 'login', function($scope, login){
login.someFunc();
login.anotherFunc();
}]);
Now the someFunc
will be visible in the scope of the returned object.
EDIT:
About the this
issue, I think you're misunderstanding how this
works in Javascript.
The this
keyword will only work "properly" in certain circumstances:
new
keywordcall
or apply
and giving it a context (this)Looking at Waxolunist's answer, I can see that the code you posted in fact works, so you're probably doing something else that's causing the error. I'm guessing it looks something like this
$scope.yetAnotherFunc = login.yetAnotherFunc
This will "detach" yetAnotherFunc
from its context, and that is why this
is not what you expect it to be.
Upvotes: 1
Reputation: 4094
Here is the solution in a fiddle:
https://jsfiddle.net/waxolunist/fcxu5eej/
HTML:
<div ng-app="app">
<div ng-controller="LoginController">
Get a Message:
<button ng-click="someFunc()">someFunc</button>
<button ng-click="anotherFunc()">anotherFunc</button>
<button ng-click="yetAnotherFunc()">yetAnotherFunc</button>
<div>Answer: {{answer}}</div>
</div>
</div>
JS:
var app = angular.module('app', []);
app.controller('LoginController', function($scope, LoginFactory) {
$scope.someFunc = function() {
$scope.answer = LoginFactory.someFunc();
}
$scope.anotherFunc = function() {
$scope.answer = LoginFactory.anotherFunc();
}
$scope.yetAnotherFunc = function() {
$scope.answer = LoginFactory.yetAnotherFunc();
}
});
app.factory('LoginFactory', [function() {
return {
someFunc: function() {
return 'abc'
},
anotherFunc : function(){
var msg = this.someFunc();
return 'Msg is '+ msg;
},
yetAnotherFunc : function(){
var msg = this.someFunc();
return 'Another msg is '+ msg;
}
}
}]);
But I really doubt that a factory is the right thing to use. Maybe a service would be better suited. But basically your code works.
Upvotes: 1