0

I have a select drop-down which displays the data either alphabetically or by relevance. It works okay but the issue I have is the data doesn't display when the page loads. It only displays after I have made a selection on the drop-down menu.

I tried adding variations of'this.sortItems();' this.sortatoz();and to mounted but this did not help.

What am I missing?

<select v-model="sortatoz" @change="sortItems">
    <option disabled value="" selected>Select</option>
    <option value="alphabetically">Alphabetically</option>
    <option value="relevance">Relevance</option>
  </select>

         <div v-for="element in copiedList" :key="element">
          <div>{{ element }}</div>
          </div>

Computed:

sortItems() {
      if (this.sortatoz === "alphabetically") {
        this.copiedList = [...this.list].sort((a, b) => (a > b ? 1 : -1));
      } else {
        if (this.sortatoz === "relevance") {
          this.copiedList = [...this.list];
        }
      }
    },

 return {
      list: ["A", "C", "B"],
      copiedList: [],
5
  • What is the initial value of this. copiedList ? Commented Aug 17, 2022 at 10:59
  • You're probably trying to do that before this.list is populated Commented Aug 17, 2022 at 11:59
  • @popnoodles How would I address that? Commented Aug 17, 2022 at 12:38
  • Show us in the question how this.list is populated, and when Commented Aug 17, 2022 at 13:03
  • I have added this in to the question. Commented Aug 17, 2022 at 13:09

1 Answer 1

1

Vuejs computed property are made to return a property and then access this property from the dom (see this)

Here, you can return a new list from the computed property and show this list from the template.

new Vue({
  el: "#app",

  data: () => ({
    list: ["A", "C", "B"],
    copiedList: [],
    sortatoz: "alphabeticallyAsc"
  }),

  computed: {
    sortedItems() {
      if (this.sortatoz === "alphabeticallyAsc") {
        return [...this.list].sort((a, b) => (a > b ? 1 : -1));
      } else if (this.sortatoz === "alphabeticallyDesc") {
        return [...this.list].sort((a, b) => (a < b ? 1 : -1));
      } else {
        if (this.sortatoz === "relevance") {
          return [...this.list];
        }
      }
    },
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">

  <select v-model="sortatoz">
    <option disabled value="" selected>Select</option>
    <option value="alphabeticallyAsc">Alphabetically ASC</option>
    <option value="alphabeticallyDesc">Alphabetically DESC</option>
    <option value="relevance">Relevance</option>
  </select>

  <div v-for="element in sortedItems" :key="element">
    <div>{{ element }}</div>
  </div>
</div>


Note : You could also have made another list and update this list onchange as you did.

You can update the list in the mounted by setting the default value of the sort and triggering the sortItems functions or more simply by making a copy of the array.

Here is an example of this implementation :

new Vue({
  el: "#app",

  data: () => ({
    list: ["A", "C", "B"],
    copiedList: [],
    sortatoz: ""
  }),
  
  mounted(){
    this.copiedList = [...this.list]
  },

  methods: {
    sortItems() {
      if (this.sortatoz === "alphabeticallyAsc") {
        this.copiedList = [...this.list].sort((a, b) => (a > b ? 1 : -1));
      } else if (this.sortatoz === "alphabeticallyDesc") {
        this.copiedList = [...this.list].sort((a, b) => (a < b ? 1 : -1));
      } else {
        if (this.sortatoz === "relevance") {
          this.copiedList = [...this.list];
        }
      }
    },
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">

  <select v-model="sortatoz"  @change="sortItems">
    <option disabled value="" selected>Select</option>
    <option value="alphabeticallyAsc">Alphabetically ASC</option>
    <option value="alphabeticallyDesc">Alphabetically DESC</option>
    <option value="relevance">Relevance</option>
  </select>

  <div v-for="element in copiedList" :key="element">
    <div>{{ element }}</div>
  </div>
</div>

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you @RenaudC5. This is a very comprehensive answer!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.