serlingpa
serlingpa

Reputation: 12710

How do I return a promise from my service to my controller?

I have asked this is several variations but I now have some definitive code that contains a bug I can't dig out.

I have an Angular service like this:

.service("lookupDataService", [
        '$q', '$http', '$timeout',  function($q, $http, $timeout) {
    this.brokers = function() {
        var cachedBrokers = localStorage.getItem("brokers");

        if (!cachedBrokers) {
            return $http.get('/api/brokers')
                .success(function (data) {
                    localStorage.setItem("brokers", data);
                });
        } else {
            return $timeout(function () {
                return {
                    "data": localStorage.getItem("brokers")
                }
            }, 1000);
        }
    }
}])

and I consume this service in my controller

$scope.loadData = function() {
    $scope.promise = $q.all([
        lookupDataService.brokers()
        .then(function(data) { $scope.enquiriesBrokers = data; }),
    ]);
};

Now I know there are several problems with this code, but I am mainly focused on trying to return a promise to my controller from the service. For example, the $q apparently does nothing with its promise, but I assure you it does later in the code.

Inspecting the data in the service retrieves the desires results, but when this trickles to the controller, the data is [Object object] rather than an array of these.

How do I return a promise when I don't have one?

Here is a sample of the JSON returned from the service:

JSON in Fiddler

And here is a sample of the HTML:

<div class="col-sm-4">
    <label for="enquiries-broker">Broker:</label>
    <select ng-model="equiriesSelectedBroker" class="form-control" ng-options="broker.brokerCodeField for broker in enquiriesBrokers" id="enquiries-broker">
        <option value="">Please select a broker</option>
    </select>
</div>

Upvotes: 0

Views: 384

Answers (1)

Jan Ranostaj
Jan Ranostaj

Reputation: 146

Use the $q object and return promise

.service("lookupDataService", [
    '$q', '$http', '$timeout',  function($q, $http, $timeout) {
this.brokers = function() {
   var defer = $q.defer()

    var cachedBrokers = localStorage.getItem("brokers");

    if (!cachedBrokers) {
          $http.get('/api/brokers')
            .success(function (data) {
                 // defer resolve
                 defer.resolve({data:data}) 
                localStorage.setItem("brokers", angular.toJson(data));
            });
    } else {
         // defer resolve
         defer.resolve({data:angular.fromJson(cachedBrokers) })
    }
   // defer return promise
   return defer.promise;
  }
 }])

So you will always get promise from service even if there is no $http call

EDIT:

Populating SELECT with JSON so the ng-model will obtain userIdField

broker.userIdField as broker.brokerCodeField for broker in enquiriesBrokers is telling that use broker.userIdField as value and broker.brokerCodeField as label

<select ng-model="equiriesSelectedBroker" class="form-control" 
ng-options="broker.userIdField as broker.brokerCodeField for broker in enquiriesBrokers" id="enquiries-broker">
    <option value="">Please select a broker</option>
</select>

Upvotes: 2

Related Questions