Skip to content

Commit

Permalink
Merge pull request canjs#2144 from canjs/2136-list-replace
Browse files Browse the repository at this point in the history
Fixes problem with an earlier promise passed to replace overwriting a later promise.
  • Loading branch information
daffl committed Dec 16, 2015
2 parents 4bf7e49 + 87ec424 commit fe21baf
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 9 deletions.
12 changes: 11 additions & 1 deletion list/list.js
Original file line number Diff line number Diff line change
Expand Up @@ -833,7 +833,17 @@ steal("can/util", "can/map", "can/map/bubble.js","can/map/map_helpers.js",functi
*/
replace: function (newList) {
if (can.isDeferred(newList)) {
newList.then(can.proxy(this.replace, this));
if(this._promise) {
this._promise.__isCurrentPromise = false;
}
var promise = this._promise = newList;
promise.__isCurrentPromise = true;
var self = this;
newList.then(function(newList){
if(promise.__isCurrentPromise) {
self.replace(newList);
}
});
} else {
this.splice.apply(this, [0, this.length].concat(can.makeArray(newList || [])));
}
Expand Down
28 changes: 28 additions & 0 deletions list/list_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -341,4 +341,32 @@ steal("can/util", "can/list", "can/test", "can/compute", "steal-qunit", function

});


test("list is always updated with the last promise passed to replace (#2136)", function(){

var list = new can.List();

stop();

list.replace( new can.Deferred( function( def ) {
setTimeout( function(){
def.resolve([ "A" ]);

setTimeout(function(){
equal(list.attr(0), "B", "list set to last promise's value");
start();
},10);

}, 20 );
}));

list.replace( new can.Deferred( function( def ) {
setTimeout( function(){
def.resolve([ "B" ]);
}, 10 );
}));
});



});
25 changes: 17 additions & 8 deletions list/promise/promise.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ steal("can/util/can.js", "can/list", function (can) {

// If there is a deferred:
if (can.isDeferred(data)) {
if(this._deferred) {
this._deferred.__cancelState = true;
}

// Set up its state. Must call this way
// because we are working on an array.
can.batch.start();
Expand All @@ -19,17 +23,22 @@ steal("can/util/can.js", "can/list", function (can) {
var self = this;
// update its state when it changes
var deferred = this._deferred = new can.Deferred();
deferred.__cancelState = false;

data.then(function(){
self.attr("state", data.state());
// The deferred methods will always return this object
deferred.resolve(self);
if(!deferred.__cancelState) {
self.attr("state", data.state());
// The deferred methods will always return this object
deferred.resolve(self);
}
},function(reason){
can.batch.start();
self.attr("state", data.state());
self.attr("reason", reason);
can.batch.stop();
deferred.reject(reason);
if(!deferred.__cancelState) {
can.batch.start();
self.attr("state", data.state());
self.attr("reason", reason);
can.batch.stop();
deferred.reject(reason);
}
});
}
return result;
Expand Down
24 changes: 24 additions & 0 deletions list/promise/promise_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,30 @@ steal("can/list/promise", "can/compute", "can/test", "steal-qunit", function ()

});

test("list is always updated with the last promise passed to replace (#2136)", function(){

var list = new can.List();

stop();

list.replace( new can.Deferred( function( def ) {
setTimeout( function(){
def.resolve([ "A" ]);

setTimeout(function(){
equal(list.attr(0), "B", "list set to last promise's value");
start();
},10);

}, 20 );
}));

list.replace( new can.Deferred( function( def ) {
setTimeout( function(){
def.resolve([ "B" ]);
}, 10 );
}));
});



Expand Down

0 comments on commit fe21baf

Please sign in to comment.