Skip to content
This repository was archived by the owner on Mar 4, 2025. It is now read-only.

Commit 185dbe7

Browse files
author
Sam Graber
authored
Merge pull request #365 from SamGraber/handle_destroy
Cancel the autosave timer on destroy
2 parents b1e7b5a + fae1583 commit 185dbe7

File tree

2 files changed

+35
-18
lines changed

2 files changed

+35
-18
lines changed

source/behaviors/autosave/autosave.tests.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import { Subject } from 'rxjs';
22
import { rlFakeAsync, mock, rlTick, flushMicrotasks } from 'rl-async-testing';
33

4-
import { services } from 'typescript-angular-utilities';
5-
64
import { AutosaveDirective, DEFAULT_AUTOSAVE_DEBOUNCE } from './autosave';
75

86
interface IFormMock {
@@ -35,7 +33,7 @@ describe('AutosaveDirective', () => {
3533

3634
autosaveAction = { trigger: sinon.spy() };
3735

38-
autosave = new AutosaveDirective(<any>form, new services.timeout.TimeoutService(), <any>autosaveAction);
36+
autosave = new AutosaveDirective(<any>form, <any>autosaveAction);
3937
});
4038

4139
describe('ngAfterViewInit', (): void => {
@@ -178,5 +176,15 @@ describe('AutosaveDirective', () => {
178176
sinon.assert.calledOnce(autosaveAction.trigger);
179177
sinon.assert.calledWith(autosaveAction.trigger, waitValue);
180178
});
179+
180+
it('should not save if the form becomes pristine immediately before saving', () => {
181+
const waitValue = mock.request()();
182+
form.submitAndWait = sinon.spy(() => waitValue);
183+
form.dirty = false;
184+
185+
autosave.autosave();
186+
187+
sinon.assert.notCalled(autosaveAction.trigger);
188+
});
181189
});
182190
});

source/behaviors/autosave/autosave.ts

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
import { Directive, Input, Self, AfterViewInit, HostListener } from '@angular/core';
2-
3-
import { services } from 'typescript-angular-utilities';
4-
import __timeout = services.timeout;
2+
import { Observable, Subject } from 'rxjs';
53

64
import { FormComponent } from '../../components/form/form';
75
import { AutosaveActionService } from '../../services/autosaveAction/autosaveAction.service';
@@ -16,44 +14,51 @@ export class AutosaveDirective implements AfterViewInit {
1614
@Input() saveWhenInvalid: boolean;
1715
@HostListener('keyup') keyupListener = this.resetDebounce;
1816

19-
timer: __timeout.ITimeout;
2017
form: FormComponent;
21-
timeoutService: __timeout.TimeoutService;
2218
autosaveAction: AutosaveActionService;
2319

20+
autosaveStart$: Subject<void> = new Subject<void>();
21+
autosaveCancel$: Subject<void> = new Subject<void>();
22+
2423
constructor( @Self() form: FormComponent
25-
, timeoutService: __timeout.TimeoutService
2624
, autosaveAction: AutosaveActionService) {
2725
this.form = form;
28-
this.timeoutService = timeoutService;
2926
this.autosaveAction = autosaveAction;
3027
}
3128

3229
ngAfterViewInit(): void {
3330
this.form.form.statusChanges.subscribe(this.setDebounce);
3431
}
3532

33+
ngOnDestroy(): void {
34+
this.autosaveCancel$.next();
35+
}
36+
3637
setDebounce = (): void => {
37-
if (!this.timer && this.form.dirty && (this.saveWhenInvalid || this.form.validate())) {
38-
this.timer = this.timeoutService.setTimeout(this.autosave, DEFAULT_AUTOSAVE_DEBOUNCE)
39-
.catch(() => null);
38+
if (this.canAutosave()) {
39+
this.autosaveCancel$.next();
40+
this.autosaveStart$.debounceTime(DEFAULT_AUTOSAVE_DEBOUNCE).takeUntil(this.autosaveCancel$).subscribe(() => this.autosave());
41+
this.autosaveStart$.next();
42+
} else {
43+
this.autosaveCancel$.next();
4044
}
4145
}
4246

4347
resetDebounce(): void {
44-
if (this.timer) {
45-
this.timer.cancel();
46-
this.timer = null;
47-
this.setDebounce();
48+
if (this.canAutosave()) {
49+
this.autosaveStart$.next();
4850
}
4951
}
5052

5153
autosave = (): void => {
54+
if (!this.canAutosave()) {
55+
return;
56+
}
57+
5258
const waitOn = this.submitAndWait();
5359
if (waitOn) {
5460
this.autosaveAction.trigger(waitOn);
5561
}
56-
this.timer = null;
5762
}
5863

5964
submitAndWait(): IWaitValue<any> {
@@ -63,4 +68,8 @@ export class AutosaveDirective implements AfterViewInit {
6368
return this.form.submitAndWait();
6469
}
6570
}
71+
72+
private canAutosave(): boolean {
73+
return this.form.dirty && (this.saveWhenInvalid || this.form.validate());
74+
}
6675
}

0 commit comments

Comments
 (0)