Skip to content

Commit

Permalink
distinctUntilChanged should set prev value with keySelector even …
Browse files Browse the repository at this point in the history
…at the first time (#6013)

* test(distintUntilChanged): new keySelector test case
(this one is for cartant)

* fix(distinctUntilChanged): use keySelector on first value too

Co-authored-by: Gabor Stefan <gabor.stefan@turicode.com>
  • Loading branch information
preda7or and Gabor Stefan authored Feb 10, 2021
1 parent a365d06 commit b0ce55b
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 6 deletions.
12 changes: 12 additions & 0 deletions spec/operators/distinctUntilChanged-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,18 @@ describe('distinctUntilChanged', () => {
});
});

it('should use the keySelector even for the first emit', () => {
testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => {
const e1 = hot(' --a--b--|', { a: 2, b: 4 });
const e1subs = ' ^-------!';
const expected = '--a-----|';
const keySelector = (x: number) => x % 2;

expectObservable(e1.pipe(distinctUntilChanged(null!, keySelector))).toBe(expected, { a: 2 });
expectSubscriptions(e1.subscriptions).toBe(e1subs);
});
});

it('should raise error when keySelector throws', () => {
testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => {
const e1 = hot(' --a--b--c--d--e--f--|');
Expand Down
10 changes: 4 additions & 6 deletions src/internal/operators/distinctUntilChanged.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,11 @@ export function distinctUntilChanged<T, K>(compare?: (a: K, b: K) => boolean, ke
let first = true;
source.subscribe(
new OperatorSubscriber(subscriber, (value) => {
// WARNING: Intentionally terse code for library size.
// If this is the first value, set the previous value state, the `1` is to allow it to move to the next
// part of the terse conditional. Then we capture `prev` to pass to `compare`, but set `prev` to the result of
// either the `keySelector` -- if provided -- or the `value`, *then* it will execute the `compare`.
// If `compare` returns truthy, it will move on to call `subscriber.next()`.
((first && ((prev = value), 1)) || !compare!(prev, (prev = keySelector ? keySelector(value) : (value as any)))) &&
const key: any = keySelector ? keySelector(value) : value;
if (first || !compare!(prev, key)) {
subscriber.next(value);
}
prev = key;
first = false;
})
);
Expand Down

0 comments on commit b0ce55b

Please sign in to comment.