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

fix($parse) - Allow setterFn to bind correctly to promise results #2854

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion src/ng/parse.js
Original file line number Diff line number Diff line change
Expand Up @@ -705,6 +705,22 @@ function parser(text, json, $filter, csp){
// Parser helper functions
//////////////////////////////////////////////////

/**
* Unwrap values from a promise
* @param {Object} obj object to unwrap
* @returns if passed a promise, the inner value. Otherwise original object.
*/
function unwrapPromise(obj){

// If we'v been passed a promise then unwrap it.
// If the value has not been resolved yet, bind to a throwaway object. This will simulate a read-only field.
if(obj && obj.then)
return obj.$$v || {}
else
return obj;
}


function setter(obj, path, setValue) {
var element = path.split('.');
for (var i = 0; element.length > 1; i++) {
Expand All @@ -714,7 +730,7 @@ function setter(obj, path, setValue) {
propertyObj = {};
obj[key] = propertyObj;
}
obj = propertyObj;
obj = unwrapPromise( propertyObj );
}
obj[element.shift()] = setValue;
return setValue;
Expand Down
45 changes: 45 additions & 0 deletions test/ng/parseSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -679,6 +679,51 @@ describe('parser', function() {
expect(scope.$eval('greeting')).toBe('hello!');
});

it('should evaluate a resolved object promise and set its value', inject(function($parse) {
var person = {'name': 'Bill Gates'};

deferred.resolve(person);
scope.person = promise;

var getter = $parse( 'person.name' );

expect(getter(scope)).toBe(undefined);
scope.$digest();
expect(getter(scope)).toBe('Bill Gates');

getter.assign(scope, 'Warren Buffet');
expect(getter(scope)).toBe('Warren Buffet');
}));

it('should evaluate a resolved primitive type promise and set its value', inject(function($parse) {
deferred.resolve("Salut!");
scope.greeting = promise;

var getter = $parse( 'greeting' );

expect(getter(scope)).toBe(undefined);
scope.$digest();
expect(getter(scope)).toBe('Salut!');

getter.assign(scope, 'Bonjour');
expect(getter(scope)).toBe('Bonjour');
}));

it('should evaluate an unresolved promise and *not* set its value', inject(function($parse) {


scope.person = promise;

var getter = $parse( 'person.name' );

expect(getter(scope)).toBe(undefined);
scope.$digest();
expect(getter(scope)).toBe(undefined);

getter.assign(scope, 'Warren Buffet');
expect(getter(scope)).toBe(undefined);
}));


it('should evaluated rejected promise and ignore the rejection reason', function() {
deferred.reject('sorry');
Expand Down