Invoke the method only upon a human's input modification in Vue.js, rather than the method itself altering the input

Recently diving into Vue, I've been working on creating a form that triggers an API call whenever an input is changed. The main goal is to dynamically populate and set other inputs based on the user's selection of a vehicle.

For example, when a user selects a make, the model and year fields are populated with appropriate values fetched from the API using WebSocket. Additionally, these fields can also be automatically filled out by entering the VIN (vehicle identification number), and any changes in one field may affect the others.

This has resulted in a feedback loop where modifying one input leads to changes in another input, triggering additional API calls and further updates.

I'm looking for ways to ensure that data is only set once after a user manually changes a field.

Below is my current code for selecting a vehicle:

<template>
  <div id="vehicleSelection">
    <h1 class="title">{{ title }}</h1>
    <b-field label="Make">
      <b-select placeholder="Select a make" v-model="make" @input="setMake(make)" id="makeSelect">
        <option
                v-for="make in make_list"
                :value="make"
                :key="make">
          {{ make }}
        </option>
      </b-select>
    </b-field>
    <b-field label="Model">
      <b-select placeholder="Select a model" v-model="model" @input="setModel(model)" id="modelSelect">
        <option
                v-for="model in model_list"
                :value="model"
                :key="model">
          {{ model }}
        </option>
      </b-select>
    </b-field>
    <b-field label="Year">
      <b-select placeholder="Select a model year" v-model="year" @input="setYear(year)" id="yearSelect">
        <option
                v-for="year in year_list"
                :value="year"
                :key="year">
          {{ year }}
        </option>
      </b-select>
    </b-field>
  </div>
</template>

<script>
  import CommandClient from '../communication/command/CommandClient';
  import MessageHandler from '../communication/handler/MessageHandler';

  export default {
    name: 'VehicleSelection',
    methods: {
      setMake(make) {
        CommandClient.send(this.$socket, CommandClient.prepare('set_vehicle_make', ['make', make]));
      },
      setModel(model) {
        CommandClient.send(this.$socket, CommandClient.prepare('set_vehicle_model', ['model', model]));
      },
      setYear(year) {
        CommandClient.send(this.$socket, CommandClient.prepare('set_vehicle_year', ['year', year]));
      },
    },
    created() {
      this.$options.sockets.onmessage = (message) => {
        MessageHandler.handle(this, message);
      };
    },
    data() {
      return {
        title: 'Vehicle Selection',
        make_list: [],
        make: null,
        model_list: [],
        model: null,
        year_list: [],
        year: null,
      };
    },
  };
</script>

Although there is some repetition in the code which will need refactoring later on, my immediate focus is on getting it to function correctly.

As for context, the MessageHandler module included here takes a Vue component as input and sets its data if the key matches in the API response:

const _ = require('lodash');

export default {
  /**
   * @param {Object} context
   * @param {MessageEvent} message
   * @return {void}
   */
  handle(context, message) {
    const messagePayload = JSON.parse(message.data);
    Object.entries(messagePayload).forEach((data) => {
      if (_.has(context.$data, data[0])) {
        context.$set(context, data[0], data[1]);
      }
    });
  },
};

Answer №1

Assuming certain aspects of your code without knowledge of all the details...

You may be experiencing a recurring cycle if you are calling the API every time a specific data property changes using `watch`. For example, consider this snippet:

data() {
  return {
    year: 2010,
  };
},
watch: {
  year() {
     // The `year` property changed due to user input or some other action.
     // API call triggered here...
     this.api();
  },
},

Your template combines `v-model` and `@input`, which can be functional but slightly confusing (remember, `v-model` is just a shorthand for `:value` and `@input`; having two `@input`s might seem odd, but it works).

If you only intend to call the API on user input, then trigger the API calls in the `@input` handlers of the UI elements that should initiate them:

<b-select :value="make" @input="setMake">

<!-- For native DOM element, use this format instead -->
<select :value="make" @input="setMake($event.target.value)">
methods: {
  // This method is *exclusively* linked to @input
  setMake(make) {
    // Update `make` based on user input
    this.make = make;

    // Only trigger API call here; while `this.make` could change through other means,
    // an API call won't be initiated in those scenarios
    this.api();
  },
},

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

Encountering an issue while attempting to utilize the .find() method in Mongoose

Currently, I am in the process of setting up a database using MongoDB and integrating the Mongoose ODM with Node.js. After running the code multiple times without any issues, I encountered an unexpected error when adding the last block to utilize the .find ...

Watch as objects materialize after using the zoom function in THREE.JS

I am facing an issue with THREE.JS involving the addition of 3D text to my scene using the following code: var loader = new THREE.FontLoader(); loader.load( '3rdparty/three.js/fonts/helvetiker_regular.typeface.json',function ( font ) { var ma ...

Issue with deploying NEXT.JS due to a failure in the build process caused by next lint

Issue I have been encountering deployment failures on Vercel due to lint errors in test files within my git repository. Despite following the recommendations from the Vercel documentation for ESLint settings, the issue persists. According to Vercel' ...

What is the best way to maintain an active listGroup even after reloading the page?

I'm currently working on a gallery project using the #listGroup bootstrap component. I would like to ensure that when a user clicks on one of the albums, the active state of the #listGroup persists even after the page is reloaded or refreshed. How can ...

Issue with Bootstrap.js causing mobile menu to not expand when toggled in Rails app

Despite adding the .toggled class, my hamburger menu is not expanding when I click on the mobile menu. I've tried adjusting the order of the required javascript commands, but it doesn't seem to be working as expected. Here are the steps I'v ...

Failed to parse module: Encountered an unexpected token while using babel-loader with BABEL_ENV set to development

I recently encountered an issue with my React project using webpack when I added the @superset-ui/embedded-sdk library via yarn. While the production build runs smoothly, the development build fails to compile. Since I am not very familiar with webpack, it ...

Programmatically simulate a text cursor activation as if the user has physically clicked on the input

I have been attempting to input a value into a text field using JavaScript, similar to the Gmail email input tag. However, I encountered an issue with some fancy animations that are tied to certain events which I am unsure how to trigger, illustrated in th ...

What is the best way to replicate the functionality of AngularJS decorators in pure vanilla JavaScript (ES6)?

Using AngularJs Decorators offers a convenient method to enhance functions in services without altering the original service. How can a similar approach be implemented with javascript classes? In my current project, I have two libraries - one containing g ...

Enhancing HTML "range" element with mouse scroll functionality for incrementing values in step increments

I'm working on developing a scroll feature that operates independently from the main window's scrolling function. I aim to trigger specific events in the primary window based on interactions with this separate scrollbar. The only solution I coul ...

The Node API is unresponsive when using Postman or accessing through the browser, as it is not returning any status code. However, no errors are displayed when

I am currently working on developing a Node API for an employee department model. I have created various requests such as 'GET', 'PUSH', 'PATCH', and 'DELETE' for both the employee and department endpoints. This deve ...

What is the functionality of the keydown event?

Whenever the input text value is not empty, I want my .removetext div to be displayed, but it's not working correctly. When I type something after the second character, my .removetext gets hidden, but it shouldn't be hidden when the input is not ...

When using res.redirect in Express, it not only redirects to a new URL but also allows you to access the HTML

I'm having an issue with redirecting a user to a login page when they click a button. Instead of being redirected, I am receiving the html source code and nothing is happening. My express redirect method is as follows: function customRedirect(req, ...

Using Javascript to Divide Table into Separate Tables each Containing a Single Row

Is there a way to divide the content of this table into three separate tables using JavaScript? It is important that each table retains its header information. Unfortunately, I am unable to modify the id's or classes as they are automatically generat ...

Display the accurate prompt in the event of 2 `catch` statements

elementX.isPresent() .then(() => { elementX.all(by.cssContainingText('option', text)).click() .catch(error => { throw {message: "Unable to select text in dropdown box"} ...

Encountering a `ECONNREFUSED` error while attempting to dispatch an action in the

I have decided to convert my Nuxt application to SSR in order to utilize nuxtServerInit and asyncData. Below are the steps I followed during this conversion process. Removed ssr: false from nuxt.config.js Dispatched actions to initialize the store's ...

Utilizing Google Maps to display an infowindow upon clicking a location from a geojson file

I want to implement info windows that pop up when markers on a map are clicked. I used the sample code provided by Google (below) to create a marker map from geojson files dragged and dropped into the window. My goal is for the info windows to show text ta ...

What could be the reason for the email not being displayed in the form?

I am attempting to automatically populate the user's email in a form when a button is clicked, preferably when the page is loaded. However, I am encountering issues with this process. This project is being developed using Google Apps Script. Code.gs ...

Even after setting the handler to return false, Angular continues to submit the form

In the following scenario, I have encountered an issue: Here is the HTML template snippet: <form [action]='endpoint' method="post" target="my_iframe" #confirmForm (ngSubmit)="submitConfirmation()"> <button type="submit" (click)="conf ...

Receiving alerts about props passed in MUI styled components triggering React's lack of recognition

I have a unique component design that requires dynamic props to determine its styling. Here is an example: const StyledTypography = styled(Typography)( ({ myColor = "black", isLarge = false }) => ({ "&&": { fontSi ...

Is there a way to use nightwatch.js to scan an entire page for broken images?

Hi there, I'm currently working on creating a test to ensure that all images are loaded on a webpage with just one single test. I assumed this would be a straightforward task that many people have already done before, but unfortunately, I haven' ...