AngularJS promises to return an empty object

Basically, what I want to do is assign a certain value to the model from a function call, which allows me to promise. In this way

value = someFun() 

This is the service I call this function from.

 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

Now it returns an empty object. What's wrong?

EDIT: As mentioned below, yes, this is one way, but let me say that I want to call SomeService.someFun in ngRepeat?

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

+2
source share
4 answers

Usually, if you want to use what is updated asynchronously to be displayed in the view without having to write controller code (which is the case in your question, since you wanted to call the function inside ng-view), then you need to return an empty placeholder object and Either combine the result of the promise into it, or update the property of this object, which you can reference in the view.

Your question is too abstract to find out how to properly approach this to make sense for your application, but here is the general (and abstracted) plunker idea 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 that is updated with the promise, and not the promise itself. If you return a promise, you need to deal with .then() , etc., in order to get the value.

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

This is how you assign a scope value.

$scope.deferredResult.text will be undefined until the promise is resolved, then it will be defined and resolved to "text" . Thus, your view should handle the undefined state for a short time - it is usually very simple to do this using ng-show .

+2
source

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> 
+1
source

promise.then() returns a promise, as indicated 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 instead assign a value to the value variable.

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> 
0
source

To expand on Ed Hinchliff's answer, if you want to return the actual object, which in turn will be filled after the promise is resolved, you can do something like this. (Similar to his answer, but using $ http as an example of an async operation). Then, instead of copying the result to the hard-coded property of the returned link to placeholder it copies all the properties from the object obtained from $ http to the existing link to the placeholder that has already been returned. This, of course, assumes that you want to return an object. I assume 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; } 
0
source

Source: https://habr.com/ru/post/975914/


All Articles