AngularJS promise returning empty object

给你一囗甜甜゛ 提交于 2019-12-24 01:54:51

问题


Basically what I want to do, is to assign some model value from function call that resolves promise. Like so

value = someFun()

This is a service from which I call this function

app.factory('SomeService', function($q) {
    return {
        someFun: function() {
            var d = $q.defer();
            try {
                d.resolve("hi");
            } catch (e) {
                d.reject(e);
            }
            return d.promise.then(function(text){
                return text;
            });
        }
    };
});

Here is the HTML code

<div ng-init="value = 'yes'">
    <pre>{{value |json}}</pre>
</div>
<button type="button" ng-click="value = someFun()">click me</button>

And this is in the controller

$scope.someFun = SomeService.someFun;

Here is plnkr

http://plnkr.co/edit/qO5ofBXZDsi3cS3bBnT8

Right now it returns an empty object. What is wrong?

EDIT: As already answered below, yes this is one way, but let's say I want to call SomeService.someFun in ngRepeat?

EDIT2: HERE IS THE ANSWER -> Angular UI Bootstrap modal inside ngRepeat


回答1:


Generally if you want to use something that is updated asynchronously to appear in a view without having to write controller code as well (which is the case in your question, as you wanted to call the function inside ng-view), then you need to return a blank placeholder object, and either merge the result of the promise into it, or update a property of that object which you can reference in the view.

Your question is too abstract to know the exact way to approach this to make sense for your application, but here is the general (and abstracted) idea plunker here:

.factory('promiseService', function($q){
  return {
    someDeferredThing: function(){
      var placeholder = {};
      var d = $q.defer();
      d.promise.then(function(text){
        placeholder.text = text;
      });
      d.resolve("hi");
      return placeholder;
    }
  }
)

The service returns an object which is updated by the promise, and not a promise itself. If you return a promise then you have to deal with .then() etc. to get the value.

.controller('appCtrl', function($scope, promiseService){
  $scope.deferredResult = promiseService.someDeferredThing();
});

This is how you assign the value to the scope.

$scope.deferredResult.text will be undefined until the promise resolves, then it will become defined and resolve to "text". As such, your view should handle the undefined state for a short duration - usually it's very simple to do that with ng-show.




回答2:


Controller.js:

  $scope.someFun = function () {
        return someservice.someFun().then(function (data) {
            $scope.value = data;
        });
    }

someservice.js:

    function someFun() {
        var d = $q.defer();
        try {
            d.resolve("hi");
        } catch (e) {
            d.reject(e);
        }
        return d.promise;
    }

html:

 <div ng-init="value = 'yes'">
                <pre>{{value |json}}</pre>
            </div>
            <button type="button" ng-click="someFun()">click me</button>



回答3:


promise.then() returns a promise as stated in the AngularJS Documentation. If you want to get the value, you should do it like this:

SomeService.someFun.then(function(text) {
  $scope.someFun = text;
});

Update:

Create a $scope function that will assign value to the value variable instead.

CONTROLLER

$scope.setValue = function() {
  SomeService.someFun.then(function(text) {
      $scope.value = text;
  });
};

HTML

<div ng-init="value = 'yes'">
    <pre>{{value |json}}</pre>
</div>
<button type="button" ng-click="setValue()">click me</button>



回答4:


To expand upon Ed Hinchliffe's answer, if you're wanting to return an actual object, which will in turn be populated once a promise is resolved, you can do something like this. (Similar to his answer, but using $http as an example async operation) Then instead of copying the result into a hard coded property of the returned reference to placeholder, it copies all properties from the object received from $http into the existing reference to placeholder which has already been returned. This is of course, assuming you are wanting to return an object. I'm assuming this is similar to how $resource works internally when returning objects.

function getObjectToBeFilledByPromise() {
    var placeholder = {};            // Create a reference to return
    var deferred = $q.defer();       // This will handle your promise

    deferred.promise.then(function(data) {  // Once our promise is resolved, populate object

        // Add all properties of data into the existing placeholder reference which was already returned
        for(var attr in data) {
            placeholder[attr] = data[attr];
        }

    });

    // Some Asynchronous Operation...
    $http({
        method: 'GET',
        url: yourUrl
    })
    .success(function(data) {
        deferred.resolve(data); // Resolve promise, which will be handled above
    })

    // Return reference as it exists now.  
    // It will be populated once the promise is resolved
    return placeholder; 
}


来源:https://stackoverflow.com/questions/25261872/angularjs-promise-returning-empty-object

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!