Resolve promise with an object with a "then" function
angularjs, promise
Solution
Solution
The `then` property that you're passing in is overriding the promise's `then` property. You instead want to return your object from within the success callback of the angular promises `then` function like this:
$scope.resolvePromise2 = function() {
deferred2.resolve({
then: function(successCB) {
successCB({myResult1:'result1',
myResult2:'result2',
'then':function() {console.log("got here")}});
}
});
};
Using the above your message is now called and you can call the `then` function in your property:
promise2.then(function(result) {
//Now we get here
$scope.messages2.push('Promise 2 then callback. Result is:' + result);
result.then();
});
Here's your updated working plunker.
Issue/Why this works
Let's look at the Angular `resolve()`:
resolve: function(val) {
if (pending) {
var callbacks = pending;
pending = undefined;
value = ref(val);
if (callbacks.length) {
nextTick(function() {
var callback;
for (var i = 0, ii = callbacks.length; i < ii; i++) {
callback = callbacks[i];
value.then(callback[0], callback[1], callback[2]);
}
});
}
}
},
Looking at `value = ref(val);` followed by `value.then(callback[0], callback[1], callback[2]);` we see that Angular attaches the `then` function to the promise as a property and that the object you passed in overrides that property. So, in your case, the passed in `then` function is called instead of `deferred.promise.then(function(result)...`.
But Angular calls your `then` function with the three callbacks (success, error, notify): `value.then(callback[0], callback[1], callback[2]);` that were saved off in `var callbacks = pending;`
So the solution is to call the first "success" callback inside your `then` function and pass it your object including the `then` property you want returned. Now the promise's `then` is called and receives your object including your `then` property
then: function(successCB) {
successCB({myResult1:'result1',
myResult2:'result2',
'then':function() {console.log("got here")}});
}
Problem
This is a bit of an abstract question, as I don't have a particular use-case right now. I've noticed that if you resolve a promise with a promise ``` var deferredA = $q.defer(); var deferredB = $q.defer(); deferredA.promise.then(function(result) { // Will get here once promiseB has been resolved. }); deferredA.resolve(deferredB.promise); ``` than promiseA isn't actually resolved until promiseB has been resolved (and then promiseA is resolved with the value of promiseB's resolution). However, what if I wanted to resolve with a value of an object with a "then" function, as: ``` var deferred = $q.defer(); deferred.promise.then(function(result) { // Aim is to get here with result = {then:function(){}}, // as though I had resolved a promise with a non-promise value, // but this function is never called }); deferred.resolve({ then: function() { } }); ``` then promiseA never actually gets resolved, as it assumed that the value is a promise, even though in the above example it's not, as in, it wasn't created with $q.defer(). There is an example plunkr at http://plnkr.co/edit/Z8XUKzxHtGBKBmgPed2q?p=preview Is there a way around this? If so, how? Edit: clarified deferred/promise & put in example "then" callbacks.