Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Callback passed to debounce method not called

Part of a small project I’m working on is the user being able to add tags to items, similarly to StackOveflow. These tags are stored in a database, so obviously I need to call an API to fetch matching tags. To prevent my API from being hit too often, I want to add a debounce method, however none of the examples I’ve found seem to work. Even lodash’s debounce method doesn’t work.

I’m currently trying this debounce method in Vue3;

const debounce = (fn: Function, delay: number): Function => {
    let timeout: NodeJS.Timeout;

    return (...args: any): void => {
        clearTimeout(timeout);
        timeout = setTimeout(() => {
            fn.apply(this, args);
        }, delay);
    };
};

onMounted(() => {
    debounce(() => console.log('hello'), 500);
});

The debounce method itself is called just fine, but the provided callback isn’t. Same goes for lodash’s debounce method, the method itself is called but whatever method I pass isn’t.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Am I missing something obvious?

Edit: I was indeed missing something obvious. The actual use case was this method (no API call yet, wanted to get the debounce method working first);

const handleTagKeyUp = (event: KeyboardEvent): void => {
    filteredTags.value = [];
    const value = inputTags.value.trim();

    if (event.code === 'Enter') {
        addTag(value);
        return;
    }

    if (value.length < 3) {
        return;
    }

    const selectedTagNames = selectedTags.value.map((t: Tag) => t.name.toLowerCase());

    filteredTags.value = props.tags.filter((t: Tag) => t.name.toLowerCase().includes(value) && ! selectedTagNames.includes(t.name.toLowerCase()));
};

which is called whenever the keyup event is fired. Simply changing it to

const handleTagKeyUp = (event: KeyboardEvent): void => {
    filteredTags.value = [];
    const value = inputTags.value.trim();

    if (event.code === 'Enter') {
        addTag(value);
        return;
    }

    if (value.length < 3) {
        return;
    }

    findTags(value);
};

const findTags = debounce((value: string) => {
    const selectedTagNames = selectedTags.value.map((t: Tag) => t.name.toLowerCase());

    filteredTags.value = props.tags.filter((t: Tag) => t.name.toLowerCase().includes(value) && ! selectedTagNames.includes(t.name.toLowerCase()));
}, 500);

fixed the issue.

>Solution :

This isn’t how debounce is used. Think about it: how would debounce respond to multiple calls to onMounted if a new debounce is created every time onMounted is called?

debounce returns a function that must be called, and calls to that returned function are denounced:

// In some scope. I don't know Vue.js
const debounced = _.debounce(() => console.log('hello'), 500);

onMounted(() => {
    debounced()
});
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading