Devesh Agrawal
Devesh Agrawal

Reputation: 9212

AngularJS watch is not hitting in controller even after making the change in Service variable

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

Answers (2)

Manish Kr. Shukla
Manish Kr. Shukla

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

JB Nizet
JB Nizet

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

Related Questions