Selecting the right <select> option in Vue 2 once the data has been retrieved from the database

In my current Vue 2 project, I am working on a small blog. The structure involves having a separate component for the post form, where one of the form inputs is a select field for the post's category. This select field should be populated with categories fetched from the database. Additionally, the component receives a post object from the parent component, which is also fetched from the database using props: ['post'].

Below is the code snippet:

// HTML
...
<select class="form-control" v-model="post.category_id">
    <option 
        v-for="cat in categories" 
        v-bind:value="cat.id">
        {{ cat.name }}
    </option>
</select>
...

// JS
module.exports = {
    props: ['post', 'url'],
    name: 'postForm',
    created: function() {
        this.syncCats()
    },
    methods: {
        syncCats: function() {
            this.$http.get("/api/categories")
            .then(function(res) {
                this.categories = res.data 
            })
        }
    },
    data: function() {
        return {
            categories: {}
        }
    }
}

The issue I am facing is that none of the options in the select field are selected by default, as shown in this image. When I open the select, both categories from the database are visible like in this image.

I aim to have the correct value automatically selected by default (post.category_id == cat.id). How can this be achieved?

I attempted using

<select ... :v-bind:selected="post.category_id == cat.id">
, but encountered the same issue.

Edit

After some testing, I outputted both post.category_id and cat.id in the following manner:

<div class="form-group">
  <label>Category</label>
  <select class="form-control" v-model="post.category_id">
    <option 
        v-for="cat in categories" 
        :value="cat.id"
        :selected="cat.id == post.category_id">
        {{ cat.name }} {{ cat.id }} {{ post.category_id }}
    </option>
  </select>
</div>

Prior to selecting any option, only the cat.id appears as seen in this image - post.category_id does not show up. However, after selecting an option, post.category_id becomes visible as illustrated in this image. It's important to note that the "1" at the end is only present in the second screenshot, indicating the value of {{ post.category_id }}.

This suggests that the post data is being loaded after the categories, necessitating a way to reinitialize the select field once the data is loaded. How could this be accomplished? For context, here is the parent component responsible for fetching the post:

<template>
    <span id="home">
        <postForm :post="post" :url="url"></postForm>
    </span>
</template>
<script>
var postForm = require('../forms/post.vue')

module.exports = {
    name: 'postEdit',
    created: function() {
        this.$http.get('api/posts/slug/' + this.$route.params.slug)
        .then(function(response) {
            if(response.status == 200) {
                this.post = response.data
                this.url = "/api/posts/slug/" + response.data.slug
            }
        })
    },
    data: function() {
        return {
            post: {},
            url: ""
        }
    },
    components: {
        postForm
    }
}
</script>

Answer №1

To properly handle selecting options in Vue, ensure to set the selected attribute on the correct <option> and follow Vue's concept of one-way data flow.

You can enhance user experience by disabling the <select> until both the post and categories are fully loaded...

<select class="form-control" 
        :disabled="!(post.category_id && categories.length)"
        @input="setCategoryId($event.target.value)">
  <option v-for="cat in categories"
          :value="cat.id"
          :selected="cat.id == post.category_id">
    {{cat.name}}
  </option>
</select>

and

methods: {
  setCategoryId(categoryId) {
    this.$emit('input', parseInt(categoryId))
  }
}

Incorporate the above code snippet into your Vue instance / component like this:

<post-form :post="post" :url="url"
           v-model="post.category_id"></post-form> 

Visit Components - Form Input Components using Custom Events for detailed guidance.

Check out the JSFiddle demo here ~ https://jsfiddle.net/1oqjojjx/267/


Just a friendly tip: initialize the categories as an array rather than an object...

data () {
  return {
    categories: []
  }
}

Answer №2

One possible approach to achieve this is as follows:

customizeMethods: {
    syncAnimalTypes: function() {
        this.$http.get("/api/animal-types")
        .then((response) => {
            this.animalTypes = response.data 
            if(!this.post.type_id) { 
               this.post.type_id = this.animalTypes[0].id
            }
        })
    }
},

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

Creating an Angular library that utilizes HTML components from the application

This is my first attempt at developing an angular library. My goal is to create a header and footer library for angular. The challenge lies in making sure that it integrates seamlessly with the HTML structure of the application it is being used in. Below ...

Text Parallax Effect

For my website, I am interested in incorporating a unique parallax effect. Instead of just fixing a background image and allowing scrolling over it, I want to apply this effect to all of the content on my site. The website consists of a single page with m ...

Encountering problem while exhibiting server's response message within a modal popup in Angular 6

I have implemented two custom dialog modals in an Angular component. The objective is to open the appropriate modal and display the response message. The component receives two values as Observables from my services: The name of the modal that needs to ...

Enhancing the appearance of a JSX component in React

I have a segment of code within my project that calculates a specific percentage and displays it on the dashboard. <text className="netProfit-circle-text" x="50%" y="50%" dy=".2em" textAnchor="middl ...

AngularJS: Blocking access to specific state for users

I am currently in the process of developing an application using sails.js for the backend and Angular for the frontend. My goal is to restrict access to the admin control page for unauthorized users. I have come across several solutions, but none of them s ...

React component not displaying styles applied with jQuery

While jQuery appears to be functioning properly within a React component, I am facing issues when trying to apply styling using jQuery in the same component. The console.log(eachVisitedTopic) statement within the loop is providing the expected results. to ...

``ScrollTop does not function properly in Safari when trying to reach the scroll

When implementing divRef.current.scrollTop = divRef.current.scrollHeight in my React project, I encountered an issue where it properly scrolled to the end in Chrome but not in Safari. divRef.current.scrollTop = divRef.current.scrollHeight ...

Using .done(), .then(), and .when() in jQuery for sequencing ajax requests in a specific order

After diving into the world of Promises in jquery and trying to avoid "callback hell" when dealing with multiple ajax requests, I still find myself without a clear answer on which method to use - whether it's .done(), .then(), or .when() - for chainin ...

What is the easiest method for querying one-to-many connections in Django?

Looking for a more efficient way to return a dictionary in JavaScript that includes data from both a Category table and Sub_category table. The desired format is 'Category1': 'Sub_cat1, Sub_cat2, ...'. Any ideas on a better approach? T ...

Tips for transferring variables in Ajax.BeginForm

Hi there! I am new to C # and I have a question about passing a string variable from C# to a function called PostFailure in JavaScript. The issue I'm facing is that the function seems to be returning some object and I am not sure where it is coming fr ...

Creating a basic bootstrap modal dialog in ASP.NET MVC: A step-by-step guide

After navigating from the login page, the user clicks on the "ForgotPassword" link and is directed to a separate page where they can fill out a form to request a new password. http://localhost:2350/Account/ForgotPassword Once the user clicks on the "Save ...

Using references to pass variables in JavaScript - passing variables to an external test in Mocha

When dealing with primitive datatypes in JavaScript, passing by reference doesn't work. One common workaround is to wrap them in an object. However, what happens if a variable starts as null and then gets reassigned as an Object before being passed to ...

Unlocking Worldwide Availability for Identifying URL Parameters

Is there a way to obtain global access to the current URL ID params? I am facing difficulty accessing the current URL ID in a child component within React. The ID is essential for querying a MongoDB database in my ChecklistTool component. Typically, I wou ...

Creating a Vuetify dialog sheet with stylish rounded edges

Is there a way to implement round corners for the dialog within the v-bottom-sheet? Note that using style="border-radius:20px;" only affects the overlay, not the dialog itself. <v-bottom-sheet style="border-radius:20px;" v-model=& ...

Does turning off javascript in a browser impact ajax requests and javascript functions?

My mind is troubled I've been thinking of options like turning off JavaScript in the browser. If I do that, then AJAX and JavaScript functions won't work, right? If so, is there a solution? ...

Discrepancy in functionality between .show() and .append() methods within JQuery

I have a container with an ID of "poidiv" that is hidden (display: none) initially. My goal is to dynamically load this container multiple times using a loop, where the maximum value for the loop is not predetermined. I attempted to achieve this using jQue ...

The choices in the cell table selection are obscured due to the select table's height when opened

I am experiencing an issue with a table where each row contains two cells with "select" options. The problem arises when I open them, as they load within the table and the available options are not clearly visible. I can only view all the options by scroll ...

Difficulty establishing a connection between NodeJS and Google Drive API

I am currently facing a challenge in my NodeJS application where I'm attempting to set up a gallery page. Despite having all the necessary configurations and connections with Google Drive API, something seems amiss when accessing the /gallery route. T ...

Are there ways to incorporate a variable within a Regular Expression in Javascript?

I've already checked the Mozilla website and W3schools, but I can't seem to find the solution. var modifyString = function (string1, string2) { if (string2.match(string1)) { string1 = new RegExp(string1); string2 = string2.replac ...

Using `useState` or `useEffect` without updating the state will lead to unnecessary re-re

Can someone explain why this render function is being called twice? const Test: React.FC = () => { const [myState, setMyState] = useState(); console.log("RENDER TEST"); return <div>test</div>; }; Interestingly, when I remove the fol ...