4

I have a service that retrieves data via REST. I want to store the resulting data in service level variable for use in multiple controllers. When I put all the REST logic directly into controllers everything works fine but when I attempt to move the retrieval / storing of data into a service the controller is not being updated when the data comes back. I've tried lots of different ways of maintain the binding between service and controller.

Controller:

myApp.controller('SiteConfigCtrl', ['$scope', '$rootScope', '$route',  'SiteConfigService',
function ($scope, $rootScope, $route, SiteConfigService) {

    $scope.init = function() {
        console.log("SiteConfigCtrl init");
        $scope.site = SiteConfigService.getConfig();
    }

}

]);

Service:

 myApp.factory('SiteConfigService', ['$http', '$rootScope', '$timeout', 'RESTService',
 function ($http, $rootScope, $timeout, RESTService) {

    var siteConfig = {} ;

    RESTService.get("https://domain/incentiveconfig", function(data) {
        siteConfig = data;
    });

    return {

        getConfig:function () {
            console.debug("SiteConfigService getConfig:");
            console.debug(siteConfig);

            return siteConfig;
        }

     };
 }
]);

View:

<div class="span4" ng-controller="SiteConfigCtrl">
            <header>
                <h2>
                    {{site.title}}
                </h2>
            </header>
2
  • probably because your service is returning you a promise and you have to use "then" function in your controller? See here for more details. johnmunsch.com/2013/07/17/angularjs-services-and-promises Commented Oct 28, 2013 at 21:58
  • I guess thats the question. How do I dynamically bind a controller to a service when the service retrieves its data asynchronously? I also only want to make the REST call once and use the local copy for the session once retrieved. Commented Oct 28, 2013 at 22:07

2 Answers 2

5

I would write it with promise factory:

myApp.factory('SiteConfigService', ['$http', '$rootScope', '$timeout', 'RESTService', '$q'
 function ($http, $rootScope, $timeout, RESTService, $q) {

    var siteConfig = {} ;

    RESTService.get("https://domain/incentiveconfig", function(data) {
        siteConfig = data;
    });

  // or just 
  // var siteConfig = RESTService.get("https://domain/incentiveconfig");

    return {

        getConfig:function () {
             var deferred = $q.defer();
             deferred.resolve(siteConfig);

              return deferred.promise;    
        }

     };
 }
]);

Controller side

         SiteConfigService.getConfig()
                    .then(function (result) {
                       $scope.site = result;                           
                    }, function (result) {
                        alert("Error: No data returned");
                    });
Sign up to request clarification or add additional context in comments.

2 Comments

I don't have fiddle/plunker but hope this example can help you: jsfiddle.net/9Ymvt/674
I have this working. I had to make mods to the code above. I'll post the full answer in awhile.
2

Solution based on Maxim's answer above - JsFiddle - http://jsfiddle.net/acb98sm/2pQ6A/6/

var myApp = angular.module('myApp',[]);

myApp.controller('SiteConfigCtrl', ['$scope', '$rootScope', '$route', 'SiteConfigService', 
function ($scope, $rootScope, $route, SiteConfigService) {

    SiteConfigService.getConfig()
            .then(function (result) {
                console.log("results are in ");
                console.log(result); 
               $scope.site = result.data; 

            }, function (result) {
                alert("Error: No data returned");
            });

}

]);

myApp.factory('SiteConfigService', ['$http', '$rootScope', '$timeout', 'RESTService', '$q',
 function ($http, $rootScope, $timeout, RESTService, $q) {

 var siteConfigFn = RESTService.get("http://graph.facebook.com/616366118/",    function(data) {
    console.log("SiteConfigService returns");
});

return {

    getConfig:function () {
         var deferred = $q.defer();
         deferred.resolve(siteConfigFn);

          return deferred.promise;    
    }

 };
 }
]);

 myApp.$inject = ['$scope', 'SiteConfigService', 'RESTService'];

 myApp.factory('RESTService',
 function ($http) {
    return {
        get:function (url, callback) {
            return $http.get(url, {withCredentials:false}).
                success(function (data, status, headers, config) {
                    callback(data);
                }).
                error(function (data, status, headers, config) {
                    console.log("failed to retrieve data");
                });
        },
        post:function (url, data, callback) {
            return $http.post(url, data, {withCredentials:true}).
                success(function (data, status, headers, config) {
                    callback(data);
                }).
                error(function (data, status, headers, config) {
                    console.log("failed to retrieve data");
                });
        }
    };
  }
);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.