-
-
Notifications
You must be signed in to change notification settings - Fork 107
feat: add debounceSignal #565
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
While the Alex and Pawal have valid points I still believe it would be a good alternative for the time being until we have some better ways of doing it inside angular or a better interface surface in angular |
|
Hi, thank you for the PR. At the moment, I'll not be accepting Personally, I think signal should not be debounced, ever. That's my personal stance (and why I feel strongly about this) |
|
I was procrastinating on the subject after the debate that I started on X surrounding the matter Where I think I found some good reasons for why I could be useful let me know what you think |
|
Hi 👋 If It's a derived signal based on Here's a possible implementation: import { linkedSignal, type ValueEqualityFn } from '@angular/core';
interface DebounceComputedOptions<S> {
equal?: ValueEqualityFn<NoInfer<S>>;
computation: () => S;
time: number;
}
export function debounceComputed<S>({ computation, time, equal }: DebounceComputedOptions<S>) {
let timeoutId: null | ReturnType<typeof setTimeout> = null;
const debounced = linkedSignal<S, S>({
equal,
source: computation,
computation: (source, previous) => {
if (timeoutId) clearTimeout(timeoutId);
timeoutId = setTimeout(() => debounced.set(source), time);
return previous?.value ?? source;
}
});
return debounced.asReadonly();
}Just wanted to share another way to approach this use case |
|
So the original reason was I raised the question on X and then some of the devs from the angular team rather wanted the debounce at the event source like on the ngModel, on the addEventlistener etc You're approach could also be an option what my implementation basically do are something similar to a computed as it creates an internal signal that are modified after the debounce So it is still a derived state that can be modified if you wanted to limit that you could just return that signal asReadonly() |
|
See #595 I think some way to defering inputs is really helpful, especially when you want a simple, yet reactive search input. I'm sure if angular ever drop observables, people will find an alternative way like I did with using libraries such as throttle-debounce in react previously. In the end, I think it always boils down to having a signal, wether or not the inputs/setters/updaters of that signal is being deferred, can be argued. As response, I would perhaps suggest a readonly signal where you do not set or update values, but rather imply the internal Subject with a |
|
@max-scopp Now i can't find it but I saw a WIP implementation of a debounce helper to use inside the signal forms callback so you have a debounce thing in there instead of on the signal type but as with a lot of the other things angular currently very experimental and might go away in the future |
|
Description
Currently it takes quite a bit of code to implement debounces in signal land if you wanna move towards becoming undependant on rxjs so the idea is to have a signal primitive that has debounce built in
This approach has an important drawback:
It uses a lot of the internals of the signal implementation that could break should the angular team decide to change the base implementation of signals. Then this would need to be updated as well
Proposed API
Usage example
Worth noting it also works with all data types ex
string,number,array,objectalso nested values i wanna emphasise this test fx for nested objectsBenefits:
More intuitive API for when having to debounce values
Clearer code intention
Easier to understand