简体   繁体   中英

Angular 1 promise in service

I've been going crazy trying to get something to work in Angular 1.3 that may not even be possible... but it seems like it should be. Basically, I'd like to write a service that returns only a calculated value, not a promise.

I have a service that makes an $http.get request and returns a promise. I'd like to call this from another service, get that data, manipulate it and return a value. I don't want to have to deal with .then once I've called my service. My reasoning is that I'd like to have a sharable function that I can call and receive an actual value so that I can use it as a condition for something like ng-show. Like I say, I'd write this function in the controller and use .then to assign a variable with the data from the promise, but I don't want to write that in every single controller I need this in.

Example:

app.factory('searchService', ['$http', function($http) {
  return {
    performSearch: function(searchString) {
      return $http.get('http://asdf.com/search/' + searchString);
    },
    getItemCount: function(itemName) {
      var _this = this;
      this.count = 0;

      this.performSearch(itemName).then(
        function successCallback(resp) {
          _this.count = resp.data.items.length;
        },
        function errorCallback() {
          // This section doesn't matter right now
        };

       return this.count;
    }
  };
}]);

So I'd like to just be able to call this from the controller and get back a "5" or something. Or even better, calling it from an ng-show like "ng-show="blahCtrl.getItemCount('item_search_string') == 0". Again, I have multiple controllers I may need this in, so I'd rather not duplicate functions all over the place just to extract that number I need.

This just doesn't work for me though... my return value is always whatever I initially set this.count to be. I've inserted a console.log a few places and have seen that (it seems) this.count is returned before the callback function can set its value. No matter what I do, I'm incapable of just returning a single value from this service and it's driving me crazy! What confuses me more is that if I were to do this code from inside the controller:

var _this = this;
searchService.performSearch('asdf').then(
  function(data) { _this.searchResults.data; }
);

It works just fine and I get my promise data right inside of the searchResults variable no problem. It just doesn't work that way inside of the service for some reason.

Hopefully this makes sense, I may have rambled a bit or been unclear. Any help would be greatly appreciated... I've spent about as much time researching this and using trial and error on my own as I can.

Thanks!

One solution as i see.

Put this once in controller

app.controller('ctrl', function ($scope, searchService) {
   $scope.searchService = searchService;
   searchService.getItemCount();
});

and get in all view

{{ searchService.count }}

And i think, it's bad to make a request for each ng-if , ng-show etc.

You are going to need to use $q ( https://docs.angularjs.org/api/ng/service/ $q). Your function is returning before the promise is fulfilled. Your getItemCount should look like this:

app.factory('searchService', ['$http', '$q', function($http, $q) {
  return {
    performSearch: function(searchString) {
      return $http.get('http://asdf.com/search/' + searchString);
    },
    getItemCount: function(itemName) {
      var deferred = $q.defer();

      this.performSearch(itemName).then(
        function successCallback(resp) {
          deferred.resolve(resp.data.items.length);
        },
        function errorCallback(err) {
          deferred.reject(err);
        };

       return deferred.promise;
    }
  };
}]);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM