Skip to content

Commit d5ccabc

Browse files
committed
fix(ng:view): ignore stale xhr callbacks
A lot of badness happens when we don't ignore stale xhrs. These raceconditions are only apparent when user clicks through the app very quckly without waiting for routes to fully load. Closes angular#619
1 parent bb94817 commit d5ccabc

File tree

2 files changed

+26
-3
lines changed

2 files changed

+26
-3
lines changed

src/widgets.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -551,13 +551,16 @@ angularWidget('ng:view', function(element) {
551551
changeCounter++;
552552
});
553553

554-
this.$watch(function() {return changeCounter;}, function() {
554+
this.$watch(function() {return changeCounter;}, function(scope, newChangeCounter) {
555555
var template = $route.current && $route.current.template;
556556
if (template) {
557557
//xhr's callback must be async, see commit history for more info
558558
$xhr('GET', template, function(code, response) {
559-
element.html(response);
560-
compiler.compile(element)($route.current.scope);
559+
// ignore callback if another route change occured since
560+
if (newChangeCounter == changeCounter) {
561+
element.html(response);
562+
compiler.compile(element)($route.current.scope);
563+
}
561564
});
562565
} else {
563566
element.html('');

test/widgetsSpec.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,26 @@ describe("widget", function() {
539539

540540
expect(rootScope.log).toEqual(['parent', 'init', 'child']);
541541
});
542+
543+
it('should discard pending xhr callbacks if a new route is requested before the current ' +
544+
'finished loading', function() {
545+
// this is a test for a bad race condition that affected feedback
546+
547+
$route.when('/foo', {template: 'myUrl1'});
548+
$route.when('/bar', {template: 'myUrl2'});
549+
550+
expect(rootScope.$element.text()).toEqual('');
551+
552+
$location.path('/foo');
553+
$browser.xhr.expectGET('myUrl1').respond('<div>{{1+3}}</div>');
554+
rootScope.$digest();
555+
$location.path('/bar');
556+
$browser.xhr.expectGET('myUrl2').respond('<div>{{1+1}}</div>');
557+
rootScope.$digest();
558+
$browser.xhr.flush(); // no that we have to requests pending, flush!
559+
560+
expect(rootScope.$element.text()).toEqual('2');
561+
});
542562
});
543563

544564

0 commit comments

Comments
 (0)