Reputation: 67
https://plnkr.co/edit/hccJqwtDlqcOBhxnwZ94?p=preview
In this example when the factory return value changes in $timeout
, the scope variable which points to the factory (in this case anotherVar
) reflects the change but the variable that points the specific property (var
) does not.
// Code goes here
angular.module("sample",[])
.controller("myctrl",function($scope,TestService){
$scope.var = TestService.name;
$scope.anotherVar = TestService;
})
.factory('TestService',function($timeout){
var ret = {};
ret.name = "temporary";
$timeout(function() {
ret.name = "final";
},4000);
return ret;
});
<!DOCTYPE html>
<html>
<head>
<script data-require="[email protected]" data-semver="1.6.6" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.6/angular.min.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-app="sample" ng-controller="myctrl">
<h1>Hello Plunker!</h1>
Value: {{var}} <br>
Another Value : {{anotherVar}}
</body>
</html>
Upvotes: 0
Views: 334
Reputation: 5185
Is not specific to angular, but with javascript, and the diffrence between pass by reference or pass by value (known in almost all of programming languages).
When you assign a variable:
var a = 3;
//then
var b = a;
// here you'expecting that b == 3, isn't it?
// well you're right!
//now let's do the following:
b = 5;
// are you expecting to see 5 into a (because b=a)?
// well, a == 3
Because the a variable was a primitive value so the affectation (b = a) was a pass by variable (=only the variable of a was set into b).
If you try now to pass by reference (using object):
var a = {}; // define a as an object
a.a = 3; // a get a property a and its value is 3
var b = a; // now the affectation is an object (=pass by reference)
// we are not assigning the value of a but its reference.
if you're changing the a property inside the b object: b.a = 5?
now if you look at the a object, you will see that a.a = 5
And that the reason of the behavior you have in you factory.
Angular factories are objects.
You are returning the object TestService
but your $scope.var
is assigned to a primitive value (TestService.name
), so when that value is changed it won't be reflected in your $scope.var
.
In the second line an object is assigned (TestService
), so if a property inside of this object chenged it will be reflected, because it is the SAME OBJECT.
To summarize:
Upvotes: 0
Reputation: 21
Your first variable, var
, has already been set based on the return value from the first factory call. Since it's scoped to the controller myCtrl
, it isn't going to look elsewhere for changes.
Your second variable, anotherVar
, is scoped to the factory, so the update in your $timeout()
is reflected.
You can read more about AngularJS scope here.
Upvotes: 1