Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit fa6e411

Browse files
committed
fix($parse): remove deprecated promise unwrapping
The feature has been deprecated in #4317 BREAKING CHANGE: promise unwrapping has been removed. It has been deprecated since 1.2.0-rc.3. It can no longer be turned on. Two methods have been removed: * $parseProvider.unwrapPromises * $parseProvider.logPromiseWarnings
1 parent 3f365f5 commit fa6e411

File tree

2 files changed

+781
-1373
lines changed

2 files changed

+781
-1373
lines changed

src/ng/parse.js

+24-220
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
'use strict';
22

33
var $parseMinErr = minErr('$parse');
4-
var promiseWarningCache = {};
5-
var promiseWarning;
64

75
// Sandboxing Angular Expressions
86
// ------------------------------
@@ -700,14 +698,6 @@ Parser.prototype = {
700698

701699
if (!o) return undefined;
702700
v = ensureSafeObject(o[i], parser.text);
703-
if (v && v.then && parser.options.unwrapPromises) {
704-
p = v;
705-
if (!('$$v' in v)) {
706-
p.$$v = undefined;
707-
p.then(function(val) { p.$$v = val; });
708-
}
709-
v = v.$$v;
710-
}
711701
return v;
712702
}, {
713703
assign: function(self, value, locals) {
@@ -835,18 +825,6 @@ function setter(obj, path, setValue, fullExp, options) {
835825
obj[key] = propertyObj;
836826
}
837827
obj = propertyObj;
838-
if (obj.then && options.unwrapPromises) {
839-
promiseWarning(fullExp);
840-
if (!("$$v" in obj)) {
841-
(function(promise) {
842-
promise.then(function(val) { promise.$$v = val; }); }
843-
)(obj);
844-
}
845-
if (obj.$$v === undefined) {
846-
obj.$$v = {};
847-
}
848-
obj = obj.$$v;
849-
}
850828
}
851829
key = ensureSafeMemberName(element.shift(), fullExp);
852830
obj[key] = setValue;
@@ -867,101 +845,30 @@ function cspSafeGetterFn(key0, key1, key2, key3, key4, fullExp, options) {
867845
ensureSafeMemberName(key3, fullExp);
868846
ensureSafeMemberName(key4, fullExp);
869847

870-
return !options.unwrapPromises
871-
? function cspSafeGetter(scope, locals) {
872-
var pathVal = (locals && locals.hasOwnProperty(key0)) ? locals : scope;
873-
874-
if (pathVal == null) return pathVal;
875-
pathVal = pathVal[key0];
848+
return function cspSafeGetter(scope, locals) {
849+
var pathVal = (locals && locals.hasOwnProperty(key0)) ? locals : scope;
876850

877-
if (!key1) return pathVal;
878-
if (pathVal == null) return undefined;
879-
pathVal = pathVal[key1];
851+
if (pathVal == null) return pathVal;
852+
pathVal = pathVal[key0];
880853

881-
if (!key2) return pathVal;
882-
if (pathVal == null) return undefined;
883-
pathVal = pathVal[key2];
854+
if (!key1) return pathVal;
855+
if (pathVal == null) return undefined;
856+
pathVal = pathVal[key1];
884857

885-
if (!key3) return pathVal;
886-
if (pathVal == null) return undefined;
887-
pathVal = pathVal[key3];
858+
if (!key2) return pathVal;
859+
if (pathVal == null) return undefined;
860+
pathVal = pathVal[key2];
888861

889-
if (!key4) return pathVal;
890-
if (pathVal == null) return undefined;
891-
pathVal = pathVal[key4];
862+
if (!key3) return pathVal;
863+
if (pathVal == null) return undefined;
864+
pathVal = pathVal[key3];
892865

893-
return pathVal;
894-
}
895-
: function cspSafePromiseEnabledGetter(scope, locals) {
896-
var pathVal = (locals && locals.hasOwnProperty(key0)) ? locals : scope,
897-
promise;
898-
899-
if (pathVal == null) return pathVal;
900-
901-
pathVal = pathVal[key0];
902-
if (pathVal && pathVal.then) {
903-
promiseWarning(fullExp);
904-
if (!("$$v" in pathVal)) {
905-
promise = pathVal;
906-
promise.$$v = undefined;
907-
promise.then(function(val) { promise.$$v = val; });
908-
}
909-
pathVal = pathVal.$$v;
910-
}
866+
if (!key4) return pathVal;
867+
if (pathVal == null) return undefined;
868+
pathVal = pathVal[key4];
911869

912-
if (!key1) return pathVal;
913-
if (pathVal == null) return undefined;
914-
pathVal = pathVal[key1];
915-
if (pathVal && pathVal.then) {
916-
promiseWarning(fullExp);
917-
if (!("$$v" in pathVal)) {
918-
promise = pathVal;
919-
promise.$$v = undefined;
920-
promise.then(function(val) { promise.$$v = val; });
921-
}
922-
pathVal = pathVal.$$v;
923-
}
924-
925-
if (!key2) return pathVal;
926-
if (pathVal == null) return undefined;
927-
pathVal = pathVal[key2];
928-
if (pathVal && pathVal.then) {
929-
promiseWarning(fullExp);
930-
if (!("$$v" in pathVal)) {
931-
promise = pathVal;
932-
promise.$$v = undefined;
933-
promise.then(function(val) { promise.$$v = val; });
934-
}
935-
pathVal = pathVal.$$v;
936-
}
937-
938-
if (!key3) return pathVal;
939-
if (pathVal == null) return undefined;
940-
pathVal = pathVal[key3];
941-
if (pathVal && pathVal.then) {
942-
promiseWarning(fullExp);
943-
if (!("$$v" in pathVal)) {
944-
promise = pathVal;
945-
promise.$$v = undefined;
946-
promise.then(function(val) { promise.$$v = val; });
947-
}
948-
pathVal = pathVal.$$v;
949-
}
950-
951-
if (!key4) return pathVal;
952-
if (pathVal == null) return undefined;
953-
pathVal = pathVal[key4];
954-
if (pathVal && pathVal.then) {
955-
promiseWarning(fullExp);
956-
if (!("$$v" in pathVal)) {
957-
promise = pathVal;
958-
promise.$$v = undefined;
959-
promise.then(function(val) { promise.$$v = val; });
960-
}
961-
pathVal = pathVal.$$v;
962-
}
963-
return pathVal;
964-
};
870+
return pathVal;
871+
};
965872
}
966873

967874
function simpleGetterFn1(key0, fullExp) {
@@ -998,9 +905,9 @@ function getterFn(path, options, fullExp) {
998905

999906
// When we have only 1 or 2 tokens, use optimized special case closures.
1000907
// http://jsperf.com/angularjs-parse-getter/6
1001-
if (!options.unwrapPromises && pathKeysLength === 1) {
908+
if (pathKeysLength === 1) {
1002909
fn = simpleGetterFn1(pathKeys[0], fullExp);
1003-
} else if (!options.unwrapPromises && pathKeysLength === 2) {
910+
} else if (pathKeysLength === 2) {
1004911
fn = simpleGetterFn2(pathKeys[0], pathKeys[1], fullExp);
1005912
} else if (options.csp) {
1006913
if (pathKeysLength < 6) {
@@ -1028,28 +935,15 @@ function getterFn(path, options, fullExp) {
1028935
// we simply dereference 's' on any .dot notation
1029936
? 's'
1030937
// but if we are first then we check locals first, and if so read it first
1031-
: '((k&&k.hasOwnProperty("' + key + '"))?k:s)') + '["' + key + '"]' + ';\n' +
1032-
(options.unwrapPromises
1033-
? 'if (s && s.then) {\n' +
1034-
' pw("' + fullExp.replace(/(["\r\n])/g, '\\$1') + '");\n' +
1035-
' if (!("$$v" in s)) {\n' +
1036-
' p=s;\n' +
1037-
' p.$$v = undefined;\n' +
1038-
' p.then(function(v) {p.$$v=v;});\n' +
1039-
'}\n' +
1040-
' s=s.$$v\n' +
1041-
'}\n'
1042-
: '');
938+
: '((k&&k.hasOwnProperty("' + key + '"))?k:s)') + '["' + key + '"]' + ';\n';
1043939
});
1044940
code += 'return s;';
1045941

1046942
/* jshint -W054 */
1047-
var evaledFnGetter = new Function('s', 'k', 'pw', code); // s=scope, k=locals, pw=promiseWarning
943+
var evaledFnGetter = new Function('s', 'k', code); // s=scope, k=locals
1048944
/* jshint +W054 */
1049945
evaledFnGetter.toString = valueFn(code);
1050-
fn = options.unwrapPromises ? function(scope, locals) {
1051-
return evaledFnGetter(scope, locals, promiseWarning);
1052-
} : evaledFnGetter;
946+
fn = evaledFnGetter;
1053947
}
1054948

1055949
// Only cache the value if it's not going to mess up the cache object
@@ -1116,103 +1010,13 @@ function $ParseProvider() {
11161010
var cache = {};
11171011

11181012
var $parseOptions = {
1119-
csp: false,
1120-
unwrapPromises: false,
1121-
logPromiseWarnings: true
1122-
};
1123-
1124-
1125-
/**
1126-
* @deprecated Promise unwrapping via $parse is deprecated and will be removed in the future.
1127-
*
1128-
* @ngdoc method
1129-
* @name $parseProvider#unwrapPromises
1130-
* @description
1131-
*
1132-
* **This feature is deprecated, see deprecation notes below for more info**
1133-
*
1134-
* If set to true (default is false), $parse will unwrap promises automatically when a promise is
1135-
* found at any part of the expression. In other words, if set to true, the expression will always
1136-
* result in a non-promise value.
1137-
*
1138-
* While the promise is unresolved, it's treated as undefined, but once resolved and fulfilled,
1139-
* the fulfillment value is used in place of the promise while evaluating the expression.
1140-
*
1141-
* **Deprecation notice**
1142-
*
1143-
* This is a feature that didn't prove to be wildly useful or popular, primarily because of the
1144-
* dichotomy between data access in templates (accessed as raw values) and controller code
1145-
* (accessed as promises).
1146-
*
1147-
* In most code we ended up resolving promises manually in controllers anyway and thus unifying
1148-
* the model access there.
1149-
*
1150-
* Other downsides of automatic promise unwrapping:
1151-
*
1152-
* - when building components it's often desirable to receive the raw promises
1153-
* - adds complexity and slows down expression evaluation
1154-
* - makes expression code pre-generation unattractive due to the amount of code that needs to be
1155-
* generated
1156-
* - makes IDE auto-completion and tool support hard
1157-
*
1158-
* **Warning Logs**
1159-
*
1160-
* If the unwrapping is enabled, Angular will log a warning about each expression that unwraps a
1161-
* promise (to reduce the noise, each expression is logged only once). To disable this logging use
1162-
* `$parseProvider.logPromiseWarnings(false)` api.
1163-
*
1164-
*
1165-
* @param {boolean=} value New value.
1166-
* @returns {boolean|self} Returns the current setting when used as getter and self if used as
1167-
* setter.
1168-
*/
1169-
this.unwrapPromises = function(value) {
1170-
if (isDefined(value)) {
1171-
$parseOptions.unwrapPromises = !!value;
1172-
return this;
1173-
} else {
1174-
return $parseOptions.unwrapPromises;
1175-
}
1176-
};
1177-
1178-
1179-
/**
1180-
* @deprecated Promise unwrapping via $parse is deprecated and will be removed in the future.
1181-
*
1182-
* @ngdoc method
1183-
* @name $parseProvider#logPromiseWarnings
1184-
* @description
1185-
*
1186-
* Controls whether Angular should log a warning on any encounter of a promise in an expression.
1187-
*
1188-
* The default is set to `true`.
1189-
*
1190-
* This setting applies only if `$parseProvider.unwrapPromises` setting is set to true as well.
1191-
*
1192-
* @param {boolean=} value New value.
1193-
* @returns {boolean|self} Returns the current setting when used as getter and self if used as
1194-
* setter.
1195-
*/
1196-
this.logPromiseWarnings = function(value) {
1197-
if (isDefined(value)) {
1198-
$parseOptions.logPromiseWarnings = value;
1199-
return this;
1200-
} else {
1201-
return $parseOptions.logPromiseWarnings;
1202-
}
1013+
csp: false
12031014
};
12041015

12051016

12061017
this.$get = ['$filter', '$sniffer', '$log', function($filter, $sniffer, $log) {
12071018
$parseOptions.csp = $sniffer.csp;
12081019

1209-
promiseWarning = function promiseWarningFn(fullExp) {
1210-
if (!$parseOptions.logPromiseWarnings || promiseWarningCache.hasOwnProperty(fullExp)) return;
1211-
promiseWarningCache[fullExp] = true;
1212-
$log.warn('[$parse] Promise found in the expression `' + fullExp + '`. ' +
1213-
'Automatic unwrapping of promises in Angular expressions is deprecated.');
1214-
};
1215-
12161020
return function(exp) {
12171021
var parsedExpression;
12181022

0 commit comments

Comments
 (0)