41

In the following code, I'm trying to use the getTranslation object to map values present in originalKeys array and push the values in a new array allKeys.

But ESLint is giving me this error, Unexpected side effect in "getkeys" computed property.

I tried shifted the getkeys function to methods, but I think that it does not make sense to call a method everytime to get the translation done. How can I solve this issue?

<template>
    <select v-model="selected">
    <option v-for="key in getkeys" v-bind:key="key"> {{ key }}</option
    </select>
</template>

data(){
    return{
    selected: '',
    allKeys: [],
    originalKeys: [],  //e.g. ["ALPHA_MIKE]
    getTranslation: {} //e.g. {"ALPHA_MIKE": "ALPHA MIKE"}
    }
},
computed: {
    getkeys(){
        let tableHeaders = [];
        for( var i=0; i<this.originalKeys.length; i++){
            let translation = this.getTranslation[this.originalKeys[i]];
            tableHeaders.push(translation);
        }
        this.selected = tableHeaders[0]; //unexpected side effect here
        this.allKeys = tableHeaders; //unexpected side effect here.
        return this.allKeys;
    }
}
2
  • You should not edit other data in computed, you should use watch instead Commented Dec 13, 2018 at 7:45
  • So do you mean that I should write the getkeys in watch? Commented Dec 13, 2018 at 7:46

4 Answers 4

61

As my above comment, you should not edit other data in computed property, you should use watch instead

computed: {
    getkeys(){
        let tableHeaders = [];
        for( var i=0; i<this.originalKeys.length; i++){
            let translation = this.getTranslation[this.originalKeys[i]];
            tableHeaders.push(translation);
        }
        return tableHeaders;
    }
},
watch: {
  getkeys: {
    deep: true,
    handler: function (newVal) {
      this.selected = newVal[0]
      this.allKeys = newVal
    }
  }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Why? Why is this a good idea? I get it that it narrows down the source of error but it's insanely infuriating since none of these quirks have any mentions in the docs.
14

As other answers mentioned this is because you are mutating the original data in a computed property. You should use a method to do this part of the job.

methods:{
    changes(tableHeaders){
        this.selected = tableHeaders[0];
        this.allKeys = tableHeaders;
    }
},
computed:{
    getkeys(){
        // Your code...
        this.changes(tableHeaders);
    }
},
data: function(){
    return{
        // Your data...
    }
}

Comments

6

ESLint is showing this error because you are mutating the original data in computed property. It is recommended that you should return new references or data from computed property.Follow this link for detailed explanation. https://github.com/vuejs/eslint-plugin-vue/blob/master/docs/rules/no-side-effects-in-computed-properties.md

Comments

0

I would advice you to move allKeys array to computed and get rid of unnecessary tableHeaders and getKeys:

<template>
    <select v-model="selected">
    <option v-for="key in allKeys" v-bind:key="key"> {{ key }}</option
    </select>
</template>

data(){
    return{
    selected: '',
    originalKeys: [],  //e.g. ["ALPHA_MIKE]
    getTranslation: {} //e.g. {"ALPHA_MIKE": "ALPHA MIKE"}
    }
},
computed: {
    allkeys() {
        return this.originalKeys.map(key => this.getTranslation[key])
    }
}

I'm not sure you need to assign this.selected = tableHeaders[0] since the first option will be chosen by default automatically.

Comments

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.