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

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 #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

+6-3
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

+20
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)