Create an AngularJS promise with no return value
Asked Answered
F

1

8

I am using $q to wrap a promise around a legacy callback. However, the existing callback doesn't have a value to return. It takes a success function with no parameters.

angular.module('MyModule').service('MyService', function() {
    function initialize() {
        var deferred = $q.defer();
        LegacyFactory.initialize(
            // 'void' Success Callback
            function () {
                deferred.resolve (/* WHAT DO I PUT HERE? */);
            },
            // Error Callback
            function (errorCode) {
                deferred.reject(errorCode);
            });
        return deferred.promise;
    }
});

I can't find a void version of resolve in the AngularJS docs. I can return a dummy value, but then clients might access that dummy value, which would cause confusion.

How do I create an AngularJS promise with no return value?

NOTE: The question AngularJS promise returning empty object is completely different. That question does return a value in the resolve function.

Frisch answered 27/9, 2014 at 0:49 Comment(6)
Just resolve with nothing.. deferred.resolve()?Meingoldas
@Meingoldas Is that possible? The docs don't mention it.Frisch
Yes you can resolve with no value. Just give it a try and see what happens.. :) plnkr.co/edit/BpYqlg?p=previewMeingoldas
I use deferred.resolve() all the time.Faliscan
@MathewFoscarini yes, but is this undocumented behavior which may change? Is there a doc somewhere mentioning this behavior?Frisch
seriously people. Don't downvote this question. It's a perfectly valid question for someone who's new to JavaScript but coming from a typed language.Faliscan
F
13

There is no void data type in JavaScript. Instead JavaScript uses the primitive type undefined that is used to represent a variable that has not been assigned a value.

A method or statement that has no return value will return undefined. A function that doesn't use the return statement will return undefined. An argument that isn't passed to a function will be undefined.

I hope you're starting to see the consistent behavior here of undefined.

function foo(x) { console.log(x); }
foo(); // will print undefined
function zoom() {}
console.log(zoom()); // will print undefined

So when you use deferred.resolve() you are passing undefined as the value for the data argument.

To more specifically answer your question.

"How do I create an AngularJS promise with no return value?"

To write JavaScript code that gives the intent of no return value for the promise. You would write this.

deferred.resolve(undefined);

That makes it clear that there is no intended data.

Later in your callback you don't have to define the data argument, but if you want you can.

 foo().then(function(data){
     if(typeof data === 'undefined') {
          // there is no data
     } else {
          // there is data
     });

if you always expect no data, then just do this.

foo().then(function(){
   // handle success
});
Faliscan answered 27/9, 2014 at 14:19 Comment(2)
Nice, detailed answer! I was under the impression that the false-y behavior of undefined would mess with the internal comparison algorithm of the promise :)Frisch
@Frisch true, but Angulars promise code doesn't touch the data value being passed to the callback. Here in the source code you can see that value is just passed as is. github.com/angular/angular.js/blob/master/src/ng/q.js#L447Faliscan

© 2022 - 2024 — McMap. All rights reserved.