Open
Description
Describe the bug
When using the scan() operator in RxJS (version 7.8.1), the accumulator parameter (a) does not correctly retain previous values across emissions. Instead, it appears to be empty or reset with each new emission, even though the index parameter (i) increments as expected. This suggests that scan() is receiving consecutive emissions but failing to persist the accumulated state.
Expected behavior
- The scan() operator should correctly accumulate all previous emissions.
- The accumulator parameter (a) should contain the history of all prior emissions, growing over time.
Index: 1
Accumulator: []
Index: 2
Accumulator: [{ time: 1711010000000, view: [expandedTabs] }]
Index: 3
Accumulator: [{ time: 1711010000000, view: [expandedTabs] }, { time: 1711010500000, view: [] }]
Actual Behavior:
- The accumulator appears empty ([]) on each emission, despite the i index increasing.
- It behaves as though scan() is reinitializing or not retaining prior emissions properly.
Index: 1
Accumulator: []
Index: 2
Accumulator: []
Index: 3
Accumulator: []
Reproduction code
import { ReplaySubject, scan, map, tap, Observable } from 'rxjs';
enum DashboardViews {
expandedTabs = 'expandedTabs'
}
const views$ = new ReplaySubject<DashboardViews[]>(1);
const viewChange$: Observable<boolean> = views$.pipe(
map(view => ({ view, time: new Date().valueOf() })),
scan((a, c, i) => {
console.log('Index:', i); // Index increases correctly
console.log('Accumulator:', a); // Accumulator is unexpectedly empty on each emission
a.push(c);
return a;
}, [] as { time: number, view: DashboardViews[] }[]),
tap(v => console.log('Accumulated values:', v)),
map((views) => {
if (views.length < 2) return false;
const curr = views[views.length - 1];
const prev = views[views.length - 2];
return prev.view.includes(DashboardViews.expandedTabs) !== curr.view.includes(DashboardViews.expandedTabs);
})
);
// Simulate emissions
views$.next([DashboardViews.expandedTabs]);
views$.next([]);
views$.next([DashboardViews.expandedTabs]);
viewChange$.subscribe(v => console.log('viewChange', v));
Reproduction URL
No response
Version
7.8.1
Environment
- RxJS version: 7.81
- Angular version: 18.2.1
- Node.js version: 20.18.1
- Browser: Chrome 133
- OS: macOS 14.7.4 (23H420)
Additional context
- The issue persists even when using shareReplay(), defer(), and ReplaySubject() with a larger buffer size, suggesting that this may be a bug in the scan() operator itself.
- The i index increasing indicates that the emissions are consecutive, yet the accumulator does not persist previous values.
- This behavior does not align with the expected behavior of scan() in RxJS.
Metadata
Metadata
Assignees
Labels
No labels