FRONTEND DEVELOPER

newsUsing Lodash/Underscore in Vue 3

Hey millionaires,
I have been working on Vue JS for a while and recently encountered a problem while trying to use Lodash in Vue Components.
The issue I faced was

this is undefined

I tried for like 2 hours but can't figure out what was going on until I found a solution and the reason of the problem.

This is due to scope of function and keywords.

following example explains the scope working differently between two function types.

// This variable is in the window's scope
window.value = 'Bound to the window';

const object = {
  // This variable is in the object's scope
  value: 'Bound to the object',
  arrowFunction: () => {
    // The arrow function uses the window's scope for `this`
    console.log(this.value); // 'Bound to the window'
  },
  regularFunction() {
    // The regular function uses the object's scope for `this`
    console.log(this.value);  // 'Bound to the object'
  }
};

This is what my vue component looked like

<template>
 <div>
  <button @click="GeneratePreview">Generate</button>
 </div>
</template>
<script>
//  LODASH
import { debounce } from "lodash";
export default {
  name: "Code Editor",
  data() {
    return 
    };
  },
  mounted() {
    this.createHTMLEditor(this.$refs.htmlEditor, "htmlmixed");
    this.createCSSEditor(this.$refs.cssEditor, "css");
    this.createJavascriptEditor(this.$refs.jsEditor, "javascript");
    this.HTMLEditor.on("change", () => {
      if (this.autoRun) {
        debounce(this.generatePreview, 250)
      }
    });
    this.CSSEditor.on("change", () => {
      if (this.autoRun) {
        debounce(this.generatePreview, 250)
      }
    });
    this.JavascriptEditor.on("change", () => {
      if (this.autoRun) {
        debounce(this.generatePreview, 250)
      }
    });
  },
  methods: {
    generatePreview() {
      this.html = this.HTMLEditor.getValue();
      this.css = this.CSSEditor.getValue();
      this.javascript = this.JavascriptEditor.getValue();
    },
  },
};
</script>

Here's the fix and proper way to use Lodash inside vue component.

created() {
  this.debouncedMethod = debounce(this.debouncedMethod, 250);
},
methods: {
  methodToDebounce() {
    // Do some things here
  }
}

so component looks like this after fixing.

<template>
 <div>
  <button @click="GeneratePreview">Generate</button>
// other bunch of code
 </div>
</template>
<script>
//  LODASH
import { debounce } from "lodash";
export default {
  name: "Code Editor",
  data() {
    return 
    };
  },
  created() {
    this.debouncedPreview = debounce(this.debouncedPreview, 250);
  },
  mounted() {
    this.createHTMLEditor(this.$refs.htmlEditor, "htmlmixed");
    this.createCSSEditor(this.$refs.cssEditor, "css");
    this.createJavascriptEditor(this.$refs.jsEditor, "javascript");
    this.HTMLEditor.on("change", () => {
      if (this.autoRun) {
        this.debouncedPreview();
      }
    });
    this.CSSEditor.on("change", () => {
      if (this.autoRun) {
        this.debouncedPreview();
      }
    });
    this.JavascriptEditor.on("change", () => {
      if (this.autoRun) {
        this.debouncedPreview();
      }
    });
  },
  methods: {
    generatePreview() {
      this.html = this.HTMLEditor.getValue();
      this.css = this.CSSEditor.getValue();
      this.javascript = this.JavascriptEditor.getValue();
    },
  },
};
</script>

That's all and that simple. All I did was wrapping our function in debounce function and returned a new one that already has debouncing built in. and now calling this.debouncedMethod() will call the debounced version.
Hope it will help you guys.

The solution is referenced from this article.