0

I have a list of blog titles stored in an array that I have printed out on the front-end. However, I can't get them in alphabetical order. My loop in Vue JS is as follows

<div id="app">
  <div>

    <input type="text" v-model="search">
    <ul>
      <li v-for="blog in filteredBlogs (sortedArray)">
        {{ blog.title }}
      </li>
    </ul>
    
  </div>
</div>

Then I have a search input which works nicely now that everything is converted to lowercase, but before searching, I just want to loop to print in alphabetical order and not just the order they are stored in the array. My JS code is as below;

new Vue({
  el: '#app',
  data() {
    return {
      search:'',
      blogs: [
        {title:"Zebra Painting Made Easy"},
        {title:"Archery - What Not To Hit"},
        {title:"Hotels To Avoid"},        
        {title:"Mice Make Good Pets"}        
      ]
    };
  },
  computed:
      filteredBlogs: function(){
          return this.blogs.filter((blog) => {
              return blog.title.toLowerCase().match(this.search.toLowerCase());
          });
      },
        
      sortedArray: function() {
      function compare(a, b) {
        if (a.title < b.title)
          return -1;
        if (a.title > b.title)
          return 1;
          return 0;
      }
      return this.arrays.sort(compare);
    }        
  }
});
1
  • The filteredBlogs computed function should return the array filtered and sorted, no need for an extra sortedArray function Commented Oct 22, 2019 at 19:13

1 Answer 1

2

You can bind the v-for directly on a computed function that returns the array filtered and sorted at the same time.

Template:

<div id="app">
  <div>
    <input type="text" v-model="search">
    <ul>
      <li v-for="blog in filteredAndSortedBlogs" :key="blog.title">
        {{ blog.title }}
      </li>
    </ul>
  </div>
</div>

Note that I've added the :key="blog.title" in the v-for element. It is recommended to provide a key attribute with v-for whenever possible, unless the iterated DOM content is simple, or you are intentionally relying on the default behavior for performance gains. See: VueJS list doc

VueJs class:

new Vue({
    el: '#app',
    data() {
        return {
            search:'',
            blogs: [
                {title:"Zebra Painting Made Easy"},
                {title:"Archery - What Not To Hit"},
                {title:"Hotels To Avoid"},        
                {title:"Mice Make Good Pets"}        
            ]
        };
    },
    computed: {
        filteredAndSortedBlogs() {
            return this.blogs
                .filter(blog => blog.title.toLowerCase().match(this.search.toLowerCase()))
                .sort((a, b) => {
                    if (a.title < b.title)
                        return -1;
                    if (a.title > b.title)
                        return 1;
                    return 0;
            });
        },
    },  
});
Sign up to request clarification or add additional context in comments.

1 Comment

Can't thank you enough. I have been really struggling with that. I know understand how I can combine both computed properties. Thank you for your guidance.

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.