From 2afcd4f384cfeb910fca59fa0ecc1ee579e95c06 Mon Sep 17 00:00:00 2001 From: Jussi Kosunen Date: Thu, 15 Aug 2013 15:14:54 +0300 Subject: [PATCH] fix(parse): handle promises returned from parsed function calls When a parsed function call returns a promise, the evaluated value is the resolved value of the promise rather than the promise object. Closes #3503 --- src/ng/parse.js | 14 +++++++++++++- test/ng/parseSpec.js | 12 ++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/ng/parse.js b/src/ng/parse.js index 9eeb1439c714..5597acd876cc 100644 --- a/src/ng/parse.js +++ b/src/ng/parse.js @@ -689,9 +689,21 @@ function parser(text, json, $filter, csp){ } var fnPtr = fn(scope, locals, context) || noop; // IE stupidity! - return fnPtr.apply + var v = fnPtr.apply ? fnPtr.apply(context, args) : fnPtr(args[0], args[1], args[2], args[3], args[4]); + + // Check for promise + if (v && v.then) { + var p = v; + if (!('$$v' in v)) { + p.$$v = undefined; + p.then(function(val) { p.$$v = val; }); + } + v = v.$$v; + } + + return v; }; } diff --git a/test/ng/parseSpec.js b/test/ng/parseSpec.js index 568a3b15bad0..d7283b3d2e75 100644 --- a/test/ng/parseSpec.js +++ b/test/ng/parseSpec.js @@ -846,6 +846,18 @@ describe('parser', function() { expect(scope.$eval('greeting')).toBe(undefined); }); + it('should evaluate a function call returning a promise and eventually get its return value', function() { + scope.greetingFn = function() { return promise; }; + expect(scope.$eval('greetingFn()')).toBe(undefined); + + scope.$digest(); + expect(scope.$eval('greetingFn()')).toBe(undefined); + + deferred.resolve('hello!'); + expect(scope.$eval('greetingFn()')).toBe(undefined); + scope.$digest(); + expect(scope.$eval('greetingFn()')).toBe('hello!'); + }); describe('assignment into promises', function() { // This behavior is analogous to assignments to non-promise values