There is a possibility of encountering an endless update loop in the watcher when utilizing the expression "tabs" error in vue

My code includes a watcher on tabs to prevent them from changing based on the values of the edit. If edit is false, then go to the next tab; otherwise, prevent the change. However, when I try to click on the tab heading to change the tab, I encounter an error mentioning "You may have an infinite update loop in watcher with expression 'tabs'". This issue is occurring due to the custom events changes_event and changes_cancel being sent to the parent from the child component.

I need assistance in identifying where I am making a mistake.

<template>
  <v-layout row wrap>
    <v-flex xs12 sm12 lg12>
      <div>
        <v-tabs v-model="tabs">
          <v-tab href="#information">INFORMATION</v-tab>
          <v-tab href="#details">DETAILS</v-tab>
          <v-tab href="#services">SERVICES</v-tab>
          <v-tab-item value="#information" v-on:changes_event="alertMessage" v-on:changes_cancel="alertPhone" id="information">
            <Information />
          </v-tab-item>
          <v-tab-item value="#details" v-on:changes_event="alertMessage" v-on:changes_cancel="alertPhone" id="details">
            <Details />
          </v-tab-item>
          <v-tab-item value="#services" v-on:changes_event="alertMessage" v-on:changes_cancel="alertPhone" id="services">
            <Services />
          </v-tab-item>
        </v-tabs>
      </div>
    </v-flex>
  </v-layout>
</template>
import Information from 'views/information/edit.vue';
import Details from 'views/details/edit.vue';
import Services from 'views/services/edit.vue';

export default {
  components: {
    Information,
    Details,
    Services,
  },
  data: function() {
    return {
      tabs: 'information',
      edit: false
    }
  },
  watch: {
    tabs(newVal, oldVal) {
      if (this.edit) {
        this.tabs = oldVal
      } else {
        this.tabs = newVal
      }
    }
  },
  methods: {
    alertMessage() {
      this.edit = true;
    },
    alertPhone() {
      this.edit = false
    }
  }
}

Answer №1

For instance, let's say the initial value for this.tabs='1'. If this.edit is set to true and this.tabs='11', then the newVal of the watch will be '11' and the oldVal will be '1'. In this scenario, this.tabs will revert to this.tabs='1' because of the condition where this.edit is true. Consequently, with newVal='1' and oldVal='11', it will lead to an infinite loop.

Vue.config.productionTip = false
new Vue ({
  el:'#app',
  data () {
      return {
        tabs: '1',
        edit: true
      }
  },
  watch: {
    tabs: function (newVal, oldVal) {
      console.log(newVal, oldVal)
      if (this.edit) this.tabs = oldVal
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="app">
    <div>
        <div>
            <input type="text" value="A" v-model="tabs">
        </div>
        <pre>{{tabs}}</pre>
    </div>
</div>

A possible solution would be to utilize the setter of a computed property.

Vue.config.productionTip = false
new Vue ({
  el:'#app',
  data () {
      return {
        tabs: '1',
        edit: true,
        tabsCopy: this.tabs
      }
  },
  computed: {
    myTabs: {
      get: function () {
        return this.tabs
      },
      set: function (newVal) {
        if (this.edit) {
          this.$forceUpdate()
          return
        }
        this.tabs= newVal
      }
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="app">
    <div>
        <div>
            <input type="checkbox" v-model="edit">
            <input type="text" v-model="myTabs">
        </div>
    </div>
</div>

Another approach is to perform the validation in @input.

Vue.config.productionTip = false
new Vue ({
  el:'#app',
  data () {
      return {
        tabs: '1',
        edit: true,
        tabsCopy: this.tabs
      }
  },
  methods: {
    changeValue: function (newVal) {
      if(this.edit) { this.$forceUpdate(); return}
      this.tabs = newVal.target.value
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="app">
    <div>
        <div>
            <input type="checkbox" v-model="edit">
            <input type="text" :value="tabs" @input="changeValue($event)">
        </div>
    </div>
</div>

An inferior workaround involves using a data property to check if newVal matches it, and if so, return immediately.

In any case, using a watch to determine whether its object needs to be changed or not is not advisable.

Therefore, utilizing the setter of a computed property solution would be a more suitable option.

Vue.config.productionTip = false
new Vue ({
  el:'#app',
  data () {
      return {
        tabs: '1',
        edit: true,
        tabsCopy: this.tabs
      }
  },
  watch: {
    tabs: function (newVal, oldVal) {
      if (newVal == this.tabsCopy) return
      if (this.edit) {
        this.tabs = oldVal
        this.tabsCopy = this.tabs
      }
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="app">
    <div>
        <div>
            <input type="checkbox" v-model="edit">
            <input type="text" v-model="tabs">
        </div>
    </div>
</div>

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

Efficiently running multiple PHP pages with just one simple click

Below is the code fragment that I currently have: <html> <script type="text/javascript"> function Run() {var a=["ONE" ,"TWO" ,"THREE", "FOUR", "FIVE"]; window.location.href = "index.php?w1=" +a;} </script> <body> <input type="b ...

Incrementing values in ng-repeat object automatically

My project involves extracting game information from mlb.com and utilizing angularjs along with the ng-repeat directive to display it. A sample of the JSON feed is shown below. { "data": { "games": { "next_day_date": "2017-08-19", "mo ...

Error encountered in ASP.NET MVC application when using jQuery POST method: data is null

I am currently utilizing a PartialView and injecting it into a <div> from another PartialView to create a popup modal using the Bootstrap Modal. Although my Bootstrap Modal is displaying correctly, it is not functioning as intended. The following are ...

Personal Information Management

After making a request for stormpath user custom data, I used the following code: res.render('home', { title: 'home', user: req.user.customData, }); Instead of receiving a JSON object of custom data as expected, a URL ('') ...

What are the possible arguments for the event type onInput?

While diving into the world of html / javascript / vue, I stumbled upon the following code snippet. <input type="text" onInput="doAction(event);"> <script> var mesdata = { message: 'type your m ...

Error with XMLHTTPRequest loading in beforeunload/unload event handlers in iOS 13.4.1 encountered

Currently, I am utilizing XMLHTTPRequest for data posting in JavaScript. Previously, it functioned smoothly on Safari and Chrome browsers up to iOS 13.3.1. However, upon updating to the latest OS version, iOS 13.4.1, an error message stating "XMLHTTPReques ...

Is there a way to upload numerous images from my local disk onto a canvas using Fabric.js?

I'm currently working on an innovative Image Collage application using the power of HTML5 canvas and Fabric.js. One of the key features I want to implement is the ability for users to simply drag and drop files into the designated 'File Drag and ...

Showing information in a table on a webpage using JavaScript and HTML

After running a console log, I am presented with the following data: 0: {smname: "thor", sim: "9976680249", pondo: "10"} 1: {smname: "asd", sim: "9999999999", pondo: "0"} 2: {smname: "asd", sim: "4444444444", pondo: "0"} 3: {smname: "bcvb", sim: "78678967 ...

The canvas grid is malfunctioning and failing to display correctly

My current code allows me to draw a grid on a canvas with multiple lines, but I'm encountering an issue when trying to render 25 or more lines - some of them don't appear on the canvas. This problem becomes more noticeable when there are 40 or mo ...

The preventDefault method is failing to prevent the default action when placed within a

I am having trouble using preventdefault to stop an action. I'm sorry if the solution is obvious, but I can't seem to locate the mistake. Why isn't it preventing the link from being followed? Here is a link to my jsfiddle: http://jsfiddle.ne ...

Display upon hovering, conceal with a button located within a popup container

There seems to be an issue with the code below. Even though it works perfectly in jsfiddle, it breaks in my Chrome and other browsers right after displaying the ".popup" div. Can anyone point out what I might be doing wrong? I found similar code on this si ...

Conceal the div by clicking outside of it

Is there a way to conceal the hidden div with the "hidden" class? I'd like for it to slide out when the user clicks outside of the hidden div. HTML <!DOCTYPE html> <html> <head> <script src="https://ajax.googleapis.c ...

Disabling a chosen option within a dropdown menu

`Hello there, I am just starting out with JavaScript and jQuery. Currently, I am developing a web application for ordering food and drinks. I have a dropdown menu for selecting breakfast items and the quantity. When the "add" button is clicked, a dynamic ...

What is the method to display all items in a Vuetify Data Table rather than limiting it to 10 rows?

I have implemented a data table from Vuetify in my project: <v-data-table :ref="`sortableTable${index}`" class="items-table-container" :headers="headers" :items="category.items" hide-default-footer> ...

The background image on Nuxt.js is not adapting to different screen sizes

My journey with developing a Nuxt app hit a snag in the CSS department early on. The issue plaguing me, as is often the case, is responsive background images. Everything looked great during testing on desktop browsers, but when I opened it up on my mobile ...

Is there a way for me to conceal my table upon clicking on the sidebar? Additionally, when I click on a button to display a different table, can the currently visible table automatically close?

I have a unique table for each button. Initially, the tables are hidden using CSS visibility: 'hidden', and when I click a button, the corresponding table displays. However, the issue arises when I click the same button again as it fails to hide ...

In React, the entire component refreshes every time the modal is opened

<ThemeProvider theme={theme}> <GlobalStyle /> {componentName !== 'questionaire' && componentName !== 'activityResult' && <CardWrapper />} <ErrorModal ...

Transform an array of strings into a JSON object or array

Is there a way to transform a JavaScript string array into a JSON string? var arr = "{'id': '10', 'name': 'test1'},{'id': '11', 'name': 'test2'}"; This would allow for easy a ...

The Ajax PHP file uploader is experiencing technical difficulties

I am currently working on an ajax image uploader that is supposed to work automatically when a user submits an image. However, I've encountered an issue where the uploader does not function as expected when I try to rename the images for ordering purp ...

To properly handle this file type in React, ensure you have the correct babel loader installed

An error is triggered when trying to compile with webpack. The message indicates that an appropriate loader may be needed to handle this file type. The libraries I am using are: Below are my project files: package.json { "name": "react", "version": ...