Make `emitOnce` be stackable to use 2 child `emitOnce` inside parent `emitOnce`
EricPoul opened this issue · 3 comments
EricPoul commented
Which @ngneat/elf-* package(s) are relevant/releated to the feature request?
store
Description
If a store is quite complex you can have 2 methods of store updating with emitOnce
inside and in the some moment you want to call these methods together but still have one emission of the store.
function updateOne() {
emitOnce(() => {
authStore.update((state) => ({
...state,
user: { id: 'foo' },
}));
authStore.update((state) => ({
...state,
user: { id: 'foo2' },
}));
});
}
function updateTwo() {
emitOnce(() => {
authStore.update((state) => ({
...state,
user: { id: 'bar' },
}));
authStore.update((state) => ({
...state,
user: { id: 'bar2' },
}));
});
}
function updateThree() {
emitOnce(() => {
updateOne();
updateTwo();
});
}
updateThree();
With the current implementation, we'll see two emissions
Proposed solution
export const batchInProgress = new BehaviorSubject<boolean>(false);
export const batchDone$ = batchInProgress.asObservable().pipe(
filter((inProgress) => !inProgress),
take(1)
);
export function emitOnce<T>(cb: () => T) {
if (!batchInProgress.getValue()) {
batchInProgress.next(true);
const value = cb();
batchInProgress.next(false);
return value;
}
return cb();
}
Alternatives considered
Do you want to create a pull request?
Yes
NetanelBasal commented
Why not remove the emitOnce from the methods and use it only in updateThree?
EricPoul commented
first two methods could be called individually
NetanelBasal commented
Let's see a PR :)