James
James

Reputation: 37

List sorting method not updating order

I'm trying to get some insight into why this sort function isn't working.

In theory, it should work the same as this: https://codepen.io/levit/pen/abmXgBR

I have a list I'm grabbing from an API:

<BookCard v-for='book in filteredBooks' :key='book.id' :book='book' />

I've got a filter for search working, but my sort isn't. Here is my data with computed properties/methods:

  data() {
    return {
      books: [],
      order: 1, // Ascending
      search: '',
    };
  },

computed: {
    filteredBooks() {
      return this.filterBySearch((this.sortByRating(this.books)));
    },
  },

  methods: {
    filterBySearch(books) {
      return books.filter((book) => book.volumeInfo.title
        .toLowerCase().match(this.search.toLowerCase()));
    },

    sortByRating(books) {
      return books
        .sort((r1, r2) => (r2.volumeInfo.averageRating - r1.volumeInfo.averageRating)
        * this.order);
    },

    sort() {
      this.order *= -1;
    },
  },

Finally, I have a button to switch the order:

<button v-bind:class="order === 1 ? 'descending' : 'ascending'" @click="sort">
  Reader Rating
</button>

Any insight into what I might be getting wrong would be very helpful as I'm new to Vue.

Thank you.

Upvotes: 1

Views: 219

Answers (1)

Boussadjra Brahim
Boussadjra Brahim

Reputation: 1

Try to not pass the data property as an argument since it's available inside the methods and just sort the filtered books not the original property because the sort affects it :

computed: {
    filteredBooks() {
      let filtered= this.filterBySearch().slice();
      return this.sortByRating(filtered)
    },
  },

  methods: {
    filterBySearch() {
      return this.books.filter((book) => book.volumeInfo.title
        .toLowerCase().match(this.search.toLowerCase()));
    },

   sortByRating(books) {
      return books.sort((r1, r2) => {
        if (
          typeof r2.volumeInfo.averageRating === "number" &&
          typeof r1.volumeInfo.averageRating === "number"
        ) {
          return (
            (r2.volumeInfo.averageRating - r1.volumeInfo.averageRating) *
            this.order
          );
        } else {
          return this.order * -1;
        }
      });
    },

    sort() {
      this.order *= -1;
    },
  },

Upvotes: 2

Related Questions