Search code examples
javascriptarraysvue.jsvuejs2vuex

How comes Vue's shared state does not get updated without parseInt?


I've noticed a minor issue in my code which I don't understand and I'm quite curious to find out why it's behaving like it is. I'm guessing its a general JavaScript thing rather than Vue.

Anyway, I am using a shared state to represent Books. However, when a book's ready attribute gets updated, the change is not reflected unless I use parseInt(filterBook.ready) when filtering the books to be displayed. By the way, filterBook.ready is an integer coming from a database. Does anyone know why this only works with parseInt()? Thanks.

This does not work:

<ul>
   <li v-for="book in this.books.all.filter(filterBook => filterBook.ready)">
      <p v-text="book.name">
   </li>
</ul>

This works:

<ul>
   <li v-for="book in this.books.all.filter(filterBook => parseInt(filterBook.ready))">
      <p v-text="book.name">
   </li>
</ul>

Solution

  • The only reasonable explanation for this is that the ready is not a number but a String. I can't see the rest of the code, so I'm making assumptions here, but this is likely because your data is coming from a REST API as JSON object/array where the ready is numeric value, but in quotes.

    if you check truthiness of a string "0", it is true, which is why you need the parseInt.

    you can validate that either using typeof in your component, or just see the data from the network panel in the dev tools.

    example test:

    <ul>
       <li v-for="book in this.books.all">
          <p v-text="typeof(book.ready)">
       </li>
    </ul>
    

    As a side note, you should avoid functions in your template and prefer to use computed, this improves performance since the computed values get cached

    <ul>
       <li v-for="book in filteredBooks">
          <p v-text="book.name">
       </li>
    </ul>
    
    computed:{
       filteredBooks: function(){
          return this.books.all.filter(filterBook => parseInt(filterBook.ready))
       }
    }