Reputation: 9212
This is my code.
sampleApp.factory('ProductService', ['$http', '$q', function ($http, $q){
var req = {
method: 'POST',
url: 'ProductData.txt',
//url: 'http://localhost/cgi-bin/superCategory.pl',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }//,
//data: { action: 'GET' }
};
var ProductService = {};
ProductService.Products = [];
return {
GetProducts: function () {
var defer = $q.defer();
$http(req).then(function(response) {
ProductService.Products = response.data;
defer.resolve(ProductService.Products);
}, function(error) {
defer.reject("Some error");
});
return defer.promise;
},
UpdateInfo: function (ProductID, VariantID) {
for (i in ProductService.Products) {
if (ProductService.Products[i].ProductID == ProductID) {
for (j in ProductService.Products[i].Variants) {
if (ProductService.Products[i].Variants[j].VariantID == VariantID) {
ProductService.Products[i].Variants[j].InCart = 1; /* Updating Info Here, But its not reflecting */
alert ('information updated'); // reaching here
break;
}
}
break;
}
}
}
};
}]);
sampleApp.controller('ProductsController', function ($scope, $routeParams, ProductService, ShoppingCartService) {
$scope.Products = [];
$scope.GetProducts = function() {
ProductService.GetProducts().then
(
function(response) {
$scope.Products = response;
},
function(error) {
alert ('error worng');
}
);
};
$scope.GetProducts();
$scope.$watch('ProductService.Products', function(newVal) {
alert ('hitting watch'); // Not Reaching Here
$scope.Products = NewVal;
alert ($scope.Products);
});
});
I am calling UpdateInfo in ProductService from some other service. Though its reaching to alert ('information updated'); in UpdateInfo. but not reaching to alert ('hitting watch'); in controller.
Can some one help me how to solve this issue?
Upvotes: 0
Views: 172
Reputation: 4477
Instead of watching ProductsService.Products and then maintaining a seperate copy of that in Scope, why not use the same value itself.
Assign a reference to the service in your scope.
$scope.ProductService = ProductService;
In this way, you're ProductService is now exposed to the view. Now in your HTML page you can directly access ProductServices.Products and as soon as the value inside the service changes, they are automatically reflected in the View.
No dirty $Watch, no separate copies.
Edit : Going by @JB's answer, you must add an attribute named Products to the Service.
Something like this
return {
Products : [],
GetProducts: function () {
var defer = $q.defer();
$http(req).then(function(response) {
ProductService.Products = response.data;
defer.resolve(ProductService.Products);
}, function(error) {
defer.reject("Some error");
});
return defer.promise;
},
........
Upvotes: 2
Reputation: 691685
Your watch is for the expression 'ProductService.Products', and is evaluated on the scope of the controller. But this expression is and always will be evaluated as undefined
, since the controller scope doesn't have a ProductService
attribute.
Note that if you did
$scope.ProductService = ProductService
it wouldn't change much. Indeed, the expression would still be undefined, since ProductService
doesn't have any attribute called Products
. The only attributes is has are GetProducts
and UpdateInfo
, of type function.
Upvotes: 2