I am new to javascript and angularjs. I'm trying to use object-oriented programming in this small project. This is my factory object:
app.factory('property',function(){
var property = function(address){
this.property = address;
};
property.prototype.setAddress = function(address){
this._address = address;
};
property.prototype.getAddress = function(){
return this._address;
};
return property;
});
I want to create the instance when a button is clicked, I'm using alert() to monitor the results, but it generates an error:
app.controller('myCtrl', ['$scope', 'property', function($scope,property){
$scope.add = function(){
var property = new property($scope.address);
alert(property.getAddress());
};
}]);
I'm getting "Error: property is not a constructor"
But if the instance is outside the function, I can call the methods, overwriting the 'Default ' value and getting a valid result. What am I doing wrong? I believe is something to do with the scopes though I don't understand much.
app.controller('myCtrl', ['$scope', 'property', function($scope,property){
var property = new property('Default');
$scope.add = function(){
property.setAddress($scope.address); // $scope.address = 'Foo'
alert(property.getAddress()); //it returns Foo
};
}]);
The issue is not with the scopes, it's with JavaScript or rather how JavaScript behaves.
JavaScript does a couple of things that aren't obviously intuitive - the one you're interested in is called "hoisting" - JS moves var declarations to the top of a function, where they serve the sole purpose of reserving this variable name as a local variable in the function's scope.
Which happens in the below code.
var property
will create a variable with undefined
. Hence when it is called it throws an error message. "property is not a constructor/ undefined is not a function
".
app.controller('myCtrl', ['$scope', 'property', function($scope,property){
$scope.add = function(){
var property = new property($scope.address);
alert(property.getAddress());
};
}]);
And in your second case,there is another unintuitive part of JS which deals with argument variables. Where arguments also declare that variable name as local to the function.
Which means below two codes are equivalent to each other.
function Foo(f) {
var f = f;
}
function Foo(f) {
f = f;
}
Hence your second code executes properly.
app.controller('myCtrl', ['$scope', 'property', function($scope,property){
var property = new property('Default');
$scope.add = function(){
property.setAddress($scope.address); // $scope.address = 'Foo'
alert(property.getAddress()); //it returns Foo
};
}]);
A good naming conventions is "Constructor functions that must be used with the new prefix should start with a capital letter".
Here in your case constructor and variable name both are same which is causing the real problem.
Hope this helps.