Skip to content

Commit 1ea70d8

Browse files
committed
fix: fix issue that prevents setting a value via state change if the same value was previously set via the view
1 parent cd8e8ff commit 1ea70d8

File tree

3 files changed

+24
-11
lines changed

3 files changed

+24
-11
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#### Bugfixes
77

88
* add support for `ngValue` on `option` elements, thereby fixing non-string option values not working for `select` elements
9+
* fix issue that prevents setting a value via state change if the same value was previously set via the view
910

1011
<a name="1.0.1"></a>
1112
### 1.0.1

src/control/directive.spec.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,16 @@ describe(NgrxFormControlDirective.name, () => {
104104
});
105105
});
106106

107+
it('should write the value when the state changes to the same value that was reported from the view before', () => {
108+
const newValue = 'new value';
109+
onChange(newValue);
110+
directive.ngrxFormControlState = { ...INITIAL_STATE, value: newValue };
111+
directive.ngrxFormControlState = INITIAL_STATE;
112+
const spy = spyOn(valueAccessor, 'writeValue');
113+
directive.ngrxFormControlState = { ...INITIAL_STATE, value: newValue };
114+
expect(spy).toHaveBeenCalledWith(newValue);
115+
});
116+
107117
// TODO: throwing error on undefined state
108118
// TODO: value conversion
109119
// TODO: mark as touched

src/control/directive.ts

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ export class NgrxFormControlDirective<TValue extends FormControlValueTypes> impl
3939
}
4040

4141
if (this.state && newState.id !== this.state.id) {
42-
this.valueWasReported = false;
43-
this.lastReportedViewValue = undefined as any;
42+
this.viewValueIsKnown = false;
43+
this.viewValue = undefined as any;
4444
}
4545

4646
this.state = newState;
@@ -72,8 +72,8 @@ export class NgrxFormControlDirective<TValue extends FormControlValueTypes> impl
7272
// types something the cursor is forced to the end of the input; to prevent this
7373
// behavior we compare the last reported value with the value to be set and filter out
7474
// those values that are equal to the last reported value
75-
private valueWasReported: boolean;
76-
private lastReportedViewValue: TValue;
75+
private viewValueIsKnown: boolean;
76+
private viewValue: TValue;
7777

7878
constructor(
7979
private el: ElementRef,
@@ -95,8 +95,8 @@ export class NgrxFormControlDirective<TValue extends FormControlValueTypes> impl
9595
this.valueAccessor.registerOnChange((newValue: TValue) => {
9696
newValue = this.convertViewValue(newValue);
9797
if (newValue !== this.state.value) {
98-
this.valueWasReported = true;
99-
this.lastReportedViewValue = newValue;
98+
this.viewValueIsKnown = true;
99+
this.viewValue = newValue;
100100
this.actionsSubject.next(new SetValueAction(this.state.id, newValue));
101101
}
102102
});
@@ -109,11 +109,13 @@ export class NgrxFormControlDirective<TValue extends FormControlValueTypes> impl
109109

110110
this.subscriptions.push(
111111
this.state$
112-
.map(s => ({ id: s.id, value: this.convertModelValue(s.value) }))
113-
.distinctUntilChanged((l, r) => l.id === r.id && l.value === r.value)
114-
.map(s => s.value)
115-
.filter(v => !this.valueWasReported || v !== this.lastReportedViewValue)
116-
.subscribe(value => this.valueAccessor.writeValue(value))
112+
.map(s => this.convertModelValue(s.value))
113+
.filter(v => !this.viewValueIsKnown || v !== this.viewValue)
114+
.subscribe(value => {
115+
this.valueAccessor.writeValue(value);
116+
this.viewValueIsKnown = true;
117+
this.viewValue = value;
118+
})
117119
);
118120

119121
if (this.valueAccessor.setDisabledState) {

0 commit comments

Comments
 (0)