Automatically choose the initial <select> option when loading asynchronous choices in Vue 3

My challenge is to bind a <select> HTML element with the v-model directive to a ref value in Vue.js 3's setup() method. I want the Form.ProductID ref to be updated when a user selects a different option.

This is the code for the <select> element:

<select v-model="Form.ProductID" id="ProductID" name="ProductID">
  <option value="1">Option A</option>
  <option value="2">Option B</option>
  <option value="3">Option C</option>
</select>

The setup() method looks like this:

export default {
  name: "ComponentProductSelector",
  setup() {
    const Form = ref({
      ProductID: '2',
      Price: null,
      Currency: null
    })

    onMounted(() => Form.value.ProductID)
    document.querySelector("#ProductID option:first-of-type")
  }
}

When inspecting the data in vue devtools on initial load, it displays as follows:

Form (Object Ref) 
    ProductID: "[object HTMLOptionElement]"

After selecting an option in the <select> element, Form.ProductID updates correctly and indicates the selected option, for example:

 Form (Object Ref) 
        ProductID: 3

The issue arises during the component's first render where the <select> element does not automatically select the option with value="2", even though it is hardcoded in the setup(). It only shows a blank option! However, changing the <select> element to the following code resolves the issue:

<select ref="Form.ProductID" id="ProductID" name="ProductID">
  <option value="1">Option A</option>
  <option value="2">Option B</option>
  <option value="3">Option C</option>
</select>

Now, the option with value="2" is selected by default upon rendering the component. However, the actual value of Form.ProductID does not update, and vue devtools still displays

ProductID: "[object HTMLOptionElement]"
as the data.

Can someone guide me on how to make the <select> element work using v-model while also selecting a default option when the component loads?

Answer №1

Answering the recent question in the comments on how to automatically select the first option when asynchronously loading data. Instead of manually manipulating the input DOM, you can set the value of Form to the first item in the options array (cloned to prevent mutation).

For instance:

<select v-model="Form.ProductID" id="ProductID" name="ProductID" v-if="options">
  <option v-for="option in options" :key="option.ProductID" :value="option.ProductID">
    {{ option.ProductID }}
  </option>
</select>
setup() {
  const options = ref(null);
  const Form = ref(null);

  axios.get('...').then(response => {
    options.value = response.data;
    Form.value = { ...options.value[0] };    // Clone and choose first option
  });
  return { options, Form }
}

There is a v-if condition on the <select> element to ensure it renders once the data is loaded.

Here's an example demonstration:

const { createApp, ref } = Vue;
const app = createApp({
  setup() {
    const options = ref(null);
    const Form = ref(null);
    
    axios.get('https://jsonplaceholder.typicode.com/posts').then(response => {
      options.value = response.data;
      Form.value = { ...options.value[0] };    // Clone and select first option
    });
    return { options, Form }
  }
});
app.mount("#app");
<div id="app">
  <select v-model="Form.id" id="ProductID" name="ProductID" v-if="options">
    <option v-for="option in options" :key="option.id" :value="option.id">
      {{ option.id }}
    </option>
  </select>
</div>

<script src="https://unpkg.com/vue@next"></script>
<script src="https://unpkg.com/axios"></script>

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

Instructions for returning a function from within another function and then displaying it upon return

My current state: constructor(props) { super(props); this.state = { temperatureConversion: '', Here is the function I'm using: handleChange = async (value) => { this.setState({ value }); await Axios.ge ...

Webpack in Vuejs does not have access to the keys defined in dev.env.js file

The framework utilized here is vuejs-webpack, with build and config files located here. No modifications have been made to these files. According to the information on Environment Variables, the keys specified in dev.env.js should be accessible during the ...

Avoiding the <br> tag in list items with TinyMCE

I am currently using tinyMCE and I needed to enable the "force_br_newlines: true" option. Without this setting, if I press the "Enter" key twice and check the source code, I only see one <br> tag. However, when I set the option to TRUE, it creates a ...

Use jQuery's .each method to reiterate through only the initial 5 elements

Is there a way to loop through just the initial 5 elements using jQuery's each method? $(".kltat").each(function() { // Restrict this to only the first five elements of the .kltat class } ...

Nuxt Static Site encountering issues with displaying dynamic content on 404 Error page

Edit I recently resolved the issue of the error template not loading correctly by fixing an htaccess problem. By adjusting the ErrorDocument to be /sub/dirs/error.html (without the dist folder), I was able to get it to work properly. However, I am still fa ...

Utilize the _sortBy function from the lodash library to arrange an array based on a specific field

Looking at an array of objects similar to this: myArray = [ {AType: "aaa", Description: "De", …}, {AType: "bbb", Description: "Hi", …}, {AType: "ccc", Description: "Un", …}, {AType: "ddd", Description: ...

Is the file corrupt using node.js?

Looking for ways to determine if a file is corrupted using node.js? I have attempted various File System methods, such as fs.readFile, fs.open, and fs.access, but all of them are showing an OK status. However, I am confident that my file is corrupted base ...

Issue with displaying content using v-show in a Nuxt.js menu

Struggling to create a mobile menu with Vue instance error The Nuxt Menu Component : <template> <header id="menu" class="menu-g"> <Nuxt-link to="/"><img src="~assets/logo.svg" alt=&qu ...

Cypress - A Guide to Efficiently Waiting for the Outcome of a Javascript Function Import

I am interested in creating a Javascript library to act as a wrapper for 3rd party APIs. I have decided to write the API wrapper as a standalone file rather than using Cypress Custom functions, so that I can share the library with teams who are not using C ...

"Engage with an Angular directive using a button positioned in any location on the

There is a directive implemented on my webpage with an assigned id attribute, regardless of its functionality. Now, I need a second directive that essentially triggers the first one. Here is an example of what I aim to achieve: <body> <!-- v ...

Leverage JSON data within an AngularJS controller

I have a JSON list in Angular that looks like this: vm.allnews = actualNews; After checking it with console.log, I can see that it's working fine and I am able to retrieve all news from the array list. Each news item has a title which I can display ...

What is the best way to display multiple values in a single column in a datatable?

This function works effectively in rendering the code: { "data": "assignedTo", "render": function (data) { var btnDetail = "<a href='/Ticket/TicketDetail?ticketI ...

Vue.js | Web scrapers struggle to track v-for generated URLs

I am currently managing a small website that utilizes Laravel and Vue.js to display a list of items. You can check it out here. It seems like the Google crawler is having trouble following the links generated by the v-for function. In my Google Search Con ...

What is the reason for the undefined output of this verified JSON Web Token (JWT)?

I've been working on decoding a JWT id_token using the libraries jwks-rsa and jsonwebtoken, however, the result keeps coming back as undefined. I understand that this issue is related to callbacks and the need to wait for a response from the getKey f ...

Is there a way to transform integers into their matching strings within Vue markup?

I have a database table where I retrieve data. The "status" field is used to manage the information in this table. If the status is equal to 1, it indicates "Active." If the status is equal to 2, it signifies "Completed." If the status is equal to 0, it r ...

Ensuring the correctness of past and upcoming dates with vee-validate in vue.js

I am currently utilizing vee-validate for the purpose of validation. <datetime v-validate="'required'" format="YYYY-MM-DD H:i:s" name="futureDates" width="100px" :class="['form-control', { ...

Adding vue template to an existing Laravel project

I recently purchased a Vue template and I am trying to integrate it into Laravel, but I keep encountering multiple 'Module not found: Error: Can't resolve '@/path';' errors. I attempted to add a resolve alias to webpack, but unfor ...

Add opening and closing HTML tags to enclose an already existing HTML structure

Is there a way to dynamically wrap the p tag inside a div with the class .description-wrapper using JavaScript or jQuery? This is the current html structure: <div class="coursePrerequisites"> <p> Lorem ipsum.. </p> </ ...

Dealing with object properties that may not always be present in Vue.js template tags

Encountering a fatal error TypeError: Cannot read properties of null (reading 'propThatSometimesDoesNotExist') when utilizing the code below: <template> <div> <img v-if="obj.propThatSometimesDoesNotExist" :src=" ...

MERN Stack deployment to Heroku: Remote rejected - unable to push changes to master branch (pre-receive hook declined)

Just a heads up: I've successfully deployed using this method around 3 times in the past, but now it seems to be failing. Could there have been an update with Heroku that's causing this issue? Not entirely sure... I'm attempting to push my ...