Using setInterval with Vue.js computed properties

Welcome to the world of Vue js! I'm currently working with some code in Para.vue that looks like this:

Para.vue

<template>
  <t-row>
    <t-col :span="13">
      <t-input
        :id="id+'_tam'"
        ref="tam"
        v-model="ayristirilmisPara.tam"
        reverse
        :label="label"
        :disabled="disabled"
        name="Oran *"
        :labelSpan="15"
        :inputSpan="8"
        :maxlength="tamMaxLength"
        :vNumber="true"
        @input="updateTam"
        v-validate="{ required: this.isRequired }"
        :error="errors.first('Oran *')"
        class="para"
      />
    </t-col>
    <t-col :span="1" style="padding-left: 0px; padding-right: 0px; padding-top: 12.5px;">,</t-col>
    <t-col :span="10">
      <t-input
        ref="kesir"
        :id="id+'_kesir'"
        v-model="ayristirilmisPara.kesir"
        :maxlength="kesirMaxLength"
        :vNumber="true"
        :disabled="disabled"
        :name="'Oran Kesir *'"
        :labelSpan="0"
        :inputSpan="18"
        label
        @input="updateKesir"
        v-validate="{ required: this.isRequired }"
        :error="errors.first('Oran Kesir *')"
        class="para"
      />
    </t-col>
    <t-col :span="1"></t-col>
  </t-row>
</template>

<script>
export default {
  props: {
    tamMaxLength: {
      type: Number,
      default: 3
    },
    kesirMaxLength: {
      type: Number,
      default: 2
    },
    value: {
      type: [String, Number],
      default: "0.00"
    },
    label: {
      type: String,
      default: "",
      required: false
    },
    isRequired: {
      type: Boolean,
      default: false,
      required: false
    },
    disabled: {
      type: Boolean,
      required: false,
      default: false
    }
  },
  data() {
    return {
      tam: "0",
      kesir: "0"
    };
  },
  methods: {
    updateTam(tam) {
      if (!tam) tam = "";
      this.tam = tam;
      this.$emit("input", `${tam}.${this.kesir}`);
    },
    updateKesir(kesir) {
      if (!kesir) kesir = "";
      this.kesir = kesir;
      this.$emit("input", `${this.tam}.${kesir}`);
    }
  },
  computed: {
    ayristirilmisPara() {
        if (this.value === undefined || this.value === null) this.value = "0.0";
        const paraParcali = this.value.toString().split(".");
        let tutar = {
          tam:
            paraParcali[0] == null
              ? 0
              : paraParcali[0] || paraParcali[0] == ""
              ? 0
              : paraParcali[0],
          kesir:
            paraParcali[1] == null
              ? 0
              : paraParcali[1] || paraParcali[1] == ""
              ? 0
              : paraParcali[1]
        };
        this.tam = tutar.tam;
        this.kesir = tutar.kesir;
        this.$emit("input", `${tutar.tam}.${tutar.kesir}`);

        return tutar;
    }
  }
};
</script>
<style>
.el-input {
  min-width: 45px;
}
.para .el-input__inner {
  padding: 0px;
}
</style>

The current functionality works perfectly fine by automatically inserting 0 when a user attempts to delete all content from the input areas with id'+_tam' and id+'_kesir'. However, now you want to implement a feature where if the user doesn't enter any input within 3 seconds, it should automatically insert 0. You tried using setInterval in the computed property but it didn't work as expected. Here's how you can achieve this:

computed: {
    ayristirilmisPara() {
      let timer = setTimeout(function() {
        if (this.value === undefined || this.value === null) this.value = "0.0";
        const paraParcali = this.value.toString().split(".");
        let tutar = {
          tam:
            paraParcali[0] == null
              ? 0
              : paraParcali[0] || paraParcali[0] == ""
              ? 0
              : paraParcali[0],
          kesir:
            paraParcali[1] == null
              ? 0
              : paraParcali[1] || paraParcali[1] == ""
              ? 0
              : paraParcali[1]
        };
        this.tam = tutar.tam;
        this.kesir = tutar.kesir;
        this.$emit("input", `${tutar.tam}.${tutar.kesir}`);

        return tutar;
      }.bind(this), 3000);
    }
  }

Give this a try and see if it solves your issue. Thank you for reaching out!

Answer №1

  1. Instead of using the "computed" section, utilize the "watch" section with the "value" watch:
watch: {
  value (newValue) {
    setInterval(...)
  }
}
  1. Ensure that the function passed to setInterval is bound to 'this' as discussed earlier here

Answer №2

In the first place, there seems to be a problem with this. When you have setInterval(function() {, the reference of this is to the function itself and not the component. One way to resolve this is by using fat arrow syntax like setInterval(() => ) or by declaring const self = this; before the function. Additionally, as suggested in the comments, consider adding the code to the watch instead of computed. Remember that when using setInterval, you should clear the interval before starting a new one to avoid creating multiple intervals unintentionally. The same applies when using setTimeout. Here's a simplified example:

data: function() {
  return {
    text: "",
    myTimeout: ""
  };
},
watch: {
  text(newValue) {
    clearTimeout(this.myTimeout);
    this.myTimeout = setTimeout(() => {
      console.log(this.text);
    }, 3000);
  }
}

Another approach is to modify the watch using function:

watch: {
  text(newValue) {
    const self = this;
    clearTimeout(this.myTimeout);
    this.myTimeout = setTimeout(function() {
      console.log(self.text);
    }, 3000);
  }
}

Check out the SANDBOX

Answer №3

The reason for this is that the return of tutar is happening within a callback function. The ayristirilmisPara() function itself is not responsible for returning tutar.

It's crucial to actually return a value from a computed property in order for Vue to properly interpret what the value should be.

Additionally, it's important to avoid changing or mutating the underlying data values within a computed property as it can lead to headaches and bugs.

  • If you need to change data, use methods
  • If you need to modify the presentation of existing data, then use computed properties

Refer to the provided resources for more detailed explanations:

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Vue component fails to render on a specific route

I am having trouble rendering the Login component on my Login Route. Here is my Login component code: <template> <v-app> <h1>Login Component</h1> </v-app> </template> <script> export default { } </script ...

Any suggestions on how to repair this Node.js login interface?

Currently grappling with setting up a Node.js application with a MySQL database to create a basic login functionality. Encountering an issue: Cannot POST /login <body class="hero-image"> <div id="container"> <div ...

What is the procedure for altering the location of a mesh within the animate() function in three.js?

In my implementation of a three.js mesh (found in three.js-master\examples\webgl_loader_collada_keyframe.html), I have a basic setup: function init() { ... ... var sphereGeometry = new THREE.SphereGeometry( 50, 32, 16 ); var sphereMater ...

Is it possible to nest ng-repeat and access $first and $last properties simultaneously

Below is the form that I am currently working with, <tbody ng-repeat="attGroup in attributesGroups"> <tr> <td class="vcenter text-right"> &nbsp;&nbsp;<a href="javascript:" ng-click="!$last && up ...

Help me understand how to display the data in a JSON array

{ "entries": [ { "id": 23931763, "url": "http://www.dailymile.com/entries/23931763", "at": "2013-07-15T21:05:39Z", "message": "I ran 3 miles and walked 2 miles today.", "comments": [], "likes": [], ...

What is the process for resetting a function within an AJAX Response?

I have implemented the code below in AJAX to switch tabs. $("a").click(function(event){ if ($.browser.msie != true && $.browser.version != 8.0){ event.preventDefault(); if ($(this).parent().hasClass("current") == false){ ...

Creating a Union Type from a JavaScript Map in Typescript

I am struggling to create a union type based on the keys of a Map. Below is a simple example illustrating what I am attempting to achieve: const myMap = new Map ([ ['one', <IconOne/>], ['two', <IconTwo/>], ['three ...

Locating the JSON path within an object

Need help with checking if a specific path is present in a JSON object? var data = { "schemaOne": { "name": "abc", "Path": "i.abc", "count": 5347, "subFolders": [ ] }, "schemaTwo": { "name": "cde", "Path": "i.cde", " ...

Sending arguments with $emit is not defined

I am having trouble passing parameters using $emit to filter out my routes in the parent component. It seems that the this.$emit() function is returning undefined on the console. What could be causing this issue? Here is the code from my Home.vue file: &l ...

Calculating the v-model name dynamically within a v-for loop

I am currently working on a form that is dynamically generated with a v-for loop. Important Note: I am utilizing "@" to escape blade in this process. My Vue instance includes the following data: data: { form: { inputs: [{icon: "", name="", ...

Guidelines for leveraging AngularJS Decorators to deactivate a button within an Html document

Currently, I am utilizing the blur admin theme and exploring the possibility of using decorators to hide a button without directly modifying the HTML. Despite my efforts, I have been unable to successfully conceal the button. Can someone provide guidance o ...

Is there a way to generate a hierarchical list menu using strings?

Within an HTML Application (HTA), I am utilizing vbscript to retrieve a list of subnet locations which is output as text in the following format: Chicago Denver Dallas Dallas/North Dallas/South Dallas/West Dallas/West/Building1 Dallas/West/Bu ...

CSS: elements that are only visible when positioned above specific elements

Can we create an element that is only visible above specific other elements? For instance, in the following code snippet, I want the .reflection element to be visible only above the .reflective elements (located at the top and bottom) and not visible on t ...

Looking for a way to convert this vue-router function into ECMAScript 2015 syntax

I am having trouble understanding how to translate the following function into ECMAScript 2015 route: { data: function () { return this.$http.get('/api/posts?sort=title&order=1').then( posts=>{thi ...

Screen content of a post request in Node.js

Can this code in node.js + express be simplified? // Code snippet for registering a new participant app.post('/api/participant', function (req, res, next) { var data = req.body; // Ensure only specific fields are uploaded var parti ...

basic handler in expressjs using the PUT method along with jQuery ajax

I am currently developing a web application utilizing a REST API for server communication. The backend is built with Node.js using Express.js. One issue I am running into is the inability to read the request body in PUT requests. Below is my client-side co ...

Ways to verify every entered word without having to click a button

My goal is to implement real-time word checking in a textarea using JavaScript/Angular. I want to validate each word as users are typing it out. What is the best approach for achieving this? ...

`I'm encountering issues when trying to pass an array through localStorage into a new array`

This is a complex and detailed question that I am struggling to find a solution for. Despite using deprecated mysql due to hosting limitations, the problem lies elsewhere. Part 1 involves dataLoader.php, which queries the database and retrieves posx and p ...

Change parent component state using a specific key-value pair

Within my React application, I am struggling to modify the parent component from a child component. I want to achieve this by calling a function in the parent component and passing both a key and a value. Here is an example of what I have attempted: var F ...

An elementary React project facing compilation issues

I'm currently exploring react hooks, but I encountered an error with the useReducer hook. The console displays the following error message: "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happe ...