Reactiveness issue with Vue JS: Javascript module variables not updating

After creating a validator module inspired by vee-validate, I wanted to use it in combination with the composition api. However, I encountered an issue where the errorMessages stored in a reactive array were not updating in the Vue template despite being stored correctly.

I'm not very experienced with this, so my explanation might not be concise. The refs in the module seem to be functioning as expected. Can someone point out what I might be doing wrong? I've hit a roadblock and don't know how to proceed further.

Validator.js (Npm module - located in node_modules)

import Vue from 'vue';
import VueCompositionAPI from '@vue/composition-api'
import {ref} from '@vue/composition-api'

Vue.use(VueCompositionAPI)

class Validator {
….

register({fieldName, rules, type}) {
    if (!fieldName || rules === null || rules === undefined) {
      console.error('Please pass in fieldName and rules');
      return false;
    }
    let errorMessages = ref([]);
    // define callback for pub-sub
    const callback = ({id, messages}) => {
      if (fieldId === id) {
        errorMessages.value = Object.assign([], messages);
        console.log(errorMessages.value); // this contains the value of the error messages.
      }
    };
    return {
      errorMessages,
    };
  }
……

InputField.vue

<template>
  <div :style="{'width': fieldWidth}" class="form-group">
    <label :for="fieldName">
      <input
        ref="inputField"
        :type="type"
        :id="fieldName"
        :name="fieldName"
        :class="[{'field-error': apiError || errorMessages.length > 0}, {'read-only-input': isReadOnly}]"
        @input="handleInput"
        v-model="input"
        class="form-input"/>
    </label>
    <div>
      <p class="text-error">{{errorMessages}}</p> // Error messages not displaying
    </div>
  </div>
</template>

<script>
  import {ref, watch} from '@vue/composition-api';
  import Validator from "validator";

  export default {
    props: {
      fieldTitle: {
        required: true
      },
      fieldName: {
        required: true
      },
      type: {
        required: true
      },
      rules: {
        default: 'required'
      }
    },
    setup(props) {
      // The error messages are returned in the component but they are not reactive. Therefore they only appear after its re-rendered.
      const {errorMessages, handleInput, setFieldData} = Validator.register(props);

      return {
        errorMessages,
        handleInput,
      }
    }
  }
</script>

Answer №1

It is advisable to utilize Vue.Set(), as it immediately prompts the update of associated values

Answer №2

The issue lies in Validator.register() destructuring props directly, resulting in the loss of reactivity from the values.

Resolution

To address this, utilize toRefs(props) to generate an object of refs for each prop and provide it to Validator.register():

import { toRefs } from 'vue'
                      👇 
Validator.register(toRefs(props))

Subsequently, adjust Validator.register() to unbox the refs when necessary:

class Validator {
  register({ fieldName, rules, type }) {
                    👇             👇                       👇
    if (!fieldName.value || rules.value === null || rules.value === undefined) {
      console.error('Please input fieldName and rules');
      return false;
    }
    ⋮
  }
}

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

Issue with CORS on Next.js static files leading to broken links on version 10.1.4

Currently, my Nextjs application is fetching its static files from Cloudfront. During deployment, I upload the /static folder to S3. After updating to version 9, I encountered a strange problem where some of my CSS files are triggering a CORS error: Acces ...

Creating customized JavaScript using jQuery for Drupal 7 Form API

Currently, I am working on developing a custom form using Drupal 7 with form API and a tableselect that includes checkboxes. I have some specific constraints for selecting the checkboxes that I intend to implement using jQuery. I created a function for han ...

Having trouble setting the focus on a text box following a custom popup

Presenting a stylish message box and attempting to focus on a textbox afterward, however, it's not functioning as expected. Below is the HTML code: <a class="fancyTrigger" href="#TheFancybox"></a> <hr> <div id="TheFancybox">& ...

Display a list of records retrieved from a Firebase query using ngFor to iterate through each instance

I'm currently using firebase and angular to work on a billing list project. The list contains data showing information for a specific month, you can refer to the imagehttps://i.stack.imgur.com/ZR4BE.png While querying the list was smooth, I encounte ...

Error: Attempting to assign value to the 'innerHTML' property of null in a Wordle clone with local storage

While developing a Wordle-inspired game for my website, I decided to utilize Local Storage to store the user's progress. Everything seemed to be working smoothly until an unexpected error occurred: "Uncaught TypeError: Cannot set properties of null (s ...

What is the best way to capture data sent by Express within a functional component?

const Header = (props) => { const [ serverData, setServerData ] = useState({}); useEffect(() => { fetch('http://localhost:4001/api') .then(res => res.json()) .then((data) => { setServerData(data); ...

The md-select search filter currently functions according to the ng-value, but it is important for it to also

I am using a md select search filter with multiple options available. For instance: id: 133, label:'Route1' id: 144, label:'Route2' id: 155, label:'Route3' id: 166, label:'Route4' If I input '1' ...

JavaScript String Splitting with Regular Expressions

It's like the solution is right in front of me, but I just can't seem to see it. var expr = "-5+6.3x24"; console.log(expr.split(/([+\-x\/])/)); The expected output should be: ["-5", "+", "6.3", "x", "24"] I want to split the string ...

To make table headers remain stationary as the data scrolls with JavaScript

When using Explorer, I was able to fix the "thead" part of my table while scrolling by using CSS expressions. The following CSS code snippet showcases how it's done: .standardTable thead tr { position: relative; top: expression(offsetParent.scrollTo ...

After making changes to the variables in my forEach loop, they revert back to their initial values

I have been attempting to create a query to retrieve all earnings and withdrawal amounts and then sum them up. However, I have encountered an issue where, after the forEach loop finishes and exits, the updated values stored in a variable revert back to t ...

What is the process for verifying the password field in bootstrap?

In my asp.net project using bootstrap, I have implemented password field validation. When the user clicks on the password field, an information box is displayed. <div id="pswd_info"> <h4>Password requirements:</h4> <ul> ...

Python and JavaScript fundamental interaction

My current setup involves having a local HTML page named leaflet.html, which is being shown in an embedded browser within a python-tkinter application. Within the leaflet.html file, there exists a straightforward JavaScript code snippet that includes a fu ...

Developing Dynamic Key-Driven State Management in ReactJS Using JavaScript

I am facing a challenge with a specific aspect of my ReactJS code, which is more about my comprehension of how JavaScript key/value arrays operate than anything else. How can I allow the key to be passed-in dynamically in the given example? The issue lies ...

Steps to making an overlapping sidebar with Bootstrap column

I'm trying to set up a sidebar in Bootstrap that overlaps with a column. The goal is for the sidebar to appear when a button is clicked and disappear when the close button x is clicked. Despite using a Bootstrap row and column layout, I encountered is ...

The ng-click functionality seems to be malfunctioning when used within the controller in conjunction with ng-bind

After coding, I noticed that my ng-click function is not working. When I inspected the element, I couldn't find ng-click displayed anywhere. Can someone please help me figure out what I'm doing wrong? var app = angular.module('myApp' ...

The results of running 'npm run dev' and 'npm run build prod' are different from each other

Currently, I am in the process of developing a progressive web app using Vue.js. During development, I utilize the command npm run dev to initiate the local server that serves the files over at http://localhost:8080/. When it comes time to build for produ ...

Retrieve data from multiple tables using knex.js

I am trying to use Express.js and knex.js to render data from two tables using only one GET function. I have successfully queried each table individually (schools or students), but I am unsure how to query both at the same time. Any ideas? app.get('/ ...

Node.JS Error: "util.TextEncoder is not a constructor" was thrown

After using browserify to bundle my js files, I encountered an error that says Uncaught TypeError: util.TextEncoder is not a constructor at Object.1.util (bundle.js:3) at o (bundle.js:1) at r (bundle.js:1) at bundle.js:1 Below are the init ...

How can you make nested JSON values optional in Joi Validation?

As I work on my API, I encounter a nested JSON structure that serves as the payload for the endpoint. Here is an example of what it looks like: {"item_id":"1245", "item_name":"asdffd", "item_Code":"1244", "attributes":[{"id":"it1","value":"1"},{"id":"it2" ...

How can I obtain the width of one element and then use it to adjust the size of another element that is

Currently, I am working on a dropdown menu and facing an issue with setting the submenus to match the width of the top-level page. In my HTML structure (specifically for a WordPress theme), it looks something like this: <ul class="menu"> <li ...