Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unexpected side effect in computed property

Tags:

vue.js

vuejs2

I'm not sure why i'm getting an unexpected side effect in computer property error with the code below.

Error:

 ✘  https://google.com/#q=vue%2Fno-side-effects-in-computed-properties  Unexpected side effect in "orderMyReposByStars" computed property            
  src/components/HelloWorld.vue:84:14
        return this.myRepos.sort((a, b) => a.stargazers_count < b.stargazers_count)

html:

<div v-if="myRepos && myRepos.length > 0">
  <h3>My Repos</h3>
  <ul>
    <li v-for="repo in orderMyReposByStars" v-bind:key="repo.id">
      <div class="repo">
        {{repo.name}}
        <div class="pull-right">
          <i class="fas fa-star"></i>
          <span class="bold">{{repo.stargazers_count}}</span>
        </div>
      </div>
    </li>
  </ul>
</div>

js:

export default {
  name: 'HelloWorld',
  data () {
    return {
      myRepos: null,  <-- THIS IS ULTIMATELY AN ARRAY OF OBJECTS
    }
  },
  computed: {
    orderMyReposByStars: function () {
      return this.myRepos.sort((a, b) => a.stargazers_count < b.stargazers_count)
    },
...

From what I can tell this looks correct according to the docs here https://v2.vuejs.org/v2/guide/list.html#Displaying-Filtered-Sorted-Results

like image 690
Catfish Avatar asked Apr 17 '18 02:04

Catfish


People also ask

Is computed property reactive?

Because computed props are reactive, whenever firstName or lastName are changed, fullName will be recomputed and will always be up to date. Already we can see an advantage of computed props over watchers. This is a fairly simple example — computed props can depend on as many other properties as you need them to.

What are computed properties?

Computed properties are part of a family of property types in Swift. Stored properties are the most common which save and return a stored value whereas computed ones are a bit different. A computed property, it's all in the name, computes its property upon request.


2 Answers

.sort mutates the original array.

To avoid it, clone the array before sorting it.

.slice() is 1 of the simplest way to clone array. See https://stackoverflow.com/a/20547803/5599288

return this.myRepos.slice().sort((a, b) => a.stargazers_count < b.stargazers_count)


on a side note, null.sort() or null.slice() will throw error. Perhaps it would be better to set the initial value of myRepos to empty array [] instead of null

like image 135
Jacob Goh Avatar answered Oct 08 '22 02:10

Jacob Goh


2021 easy & readable solution...

Just the use spread syntax:

computed: {
  orderMyReposByStars: function () {
     return [...this.myRepos].sort((a, b) => a.stargazers_count < b.stargazers_count)
  },
}
like image 25
maxshuty Avatar answered Oct 08 '22 04:10

maxshuty