How to use Lodash debounce in VueJs watch with Typescript
Asked Answered
T

2

8

In VueJS (Javascript) I can do this:

import debounce from "lodash/debounce";

...

watch: {
  variable: debounce(function() {
    console.log('wow');
  }, 500)
}

In VueJS (Typescript) I try:

npm i lodash-es
npm i @types/lodash-es -D

In component:

import { Component, Vue, Watch } from "vue-property-decorator";
import debounce from "lodash-es/debounce";

...

@Watch("variable")
debounce(function() {
  console.log('wow');
}, 500)

But I get errors:

  • 'debounce', which lacks return-type annotation, implicitly has an 'any' return type.
  • Member '500' implicitly has an 'any' type.

P.S. This works fine:

func = debounce(() => {
    console.log('wow');
}, 500)
Tressatressia answered 4/9, 2019 at 13:43 Comment(3)
From an initial glance, this appears to be correct. Did you restart your build tool (TypeScript or webpack or something else) and try restarting your editor (or the TypeScript server in your editor)?Acetamide
I use VScode and Vue-CLI with TypeScript, and yes i restart but result the same :-( I think the problem in '@Watch' and how it works, unfortunately i don't have deep knowledge about TypeScript and it's decorators.Tressatressia
"How to make life harder with TypeScript"Kathyrnkati
S
12
@Watch("variable")
debounce(function() {
  console.log('wow');
}, 500)

isn't a correct syntax. A decorator is supposed to be applied to class member but no name was specified.

There's no straightforward way to use Lodash debounce with Watch decorator because the latter is supposed to be used with prototype method.

It's possible to make it a decorator and chain them but this will likely result in undesirable behaviour because debounce interval will be shared through prototype method between all component instances:

function Debounce(delay: number) {
  return (target: any, prop: string) => {
    return {
        configurable: true,
        enumerable: false,
        value: debounce(target[prop], delay)
    };
  }
}

...
@Watch('variable')
@Debounce(500)
onVariable() { ... }
...

This likely should be achieved by debouncing instance method, similarly to how the documentation suggests:

...
created() {
  this.onDebouncedVariable = debounce(this.onDebouncedVariable, 1000);
}

@Watch('count')
onVariable() {
    this.onDebouncedVariable();
}

onDebouncedVariable() { ... }
...
Sacramentalist answered 4/9, 2019 at 15:46 Comment(0)
D
0

You can use this: https://www.npmjs.com/package/vue-debounce-decorator

And then do this:

  @Watch('value')
  @Debounce(300)
  private onValueChanged (val: string): void {
    // do your thing here
  }
Deputation answered 14/2, 2020 at 22:47 Comment(1)
The access specifier "private" shouldn't go there. The code won't compile if you put it. Other than that, it worked for me, a great way to keep code minimalistic :)Nativeborn

© 2022 - 2024 — McMap. All rights reserved.