Computed property not updating on props changes

Viewed 5539

I can't get a computed property to update, when a nested property in a passed prop object is changed.

this.favourite is passed via props, but the computed property is not updating when this.favourite.selectedChoices.second.id and this.favourite.selectedChoices.first.id is changed.

Any ideas of how to make this reactive?

Here's the computed property:

isDisabled() {
  const hasMultipleChoices = this.favourite.choices.length
    ? this.favourite.choices[0].value.some(value => value.choices.length) : 
    false;

  if (hasMultipleChoices && !this.favourite.selectedChoices.second.id) {
    return true;
  } else if (this.favourite.choices.length && !this.favourite.selectedChoices.first.id) {
    return true;
  }

  return false;
}
2 Answers

TESTED

In my test.vue

props: {
    variant: {
      type: String,
      default: ''
    }
}

const myComputedName = computed(() => {
  return {
    'yellow--warning': props.variant === 'yellow',
    'red--warning': props.variant === 'red',
  }
})

test.spec.js

    import { shallowMount } from '@vue/test-utils'
    import test from '@/components/test.vue'
    let wrapper
    
    //default values
    function createConfig(overrides) {
      let variant = ''
      const propsData = { variant }
      return Object.assign({ propsData }, overrides)
    }
    //test
    describe('test.vue Implementation Test', () => {
      let wrapper
    
      // TEARDOWN - run after to each unit test
      afterEach(() => {
        wrapper.destroy()
      })
      it('computed return red if prop variant is red', async (done) => {
        const config = createConfig({ propsData: { variant: 'red' } })
        wrapper = shallowMount(test, config)
        wrapper.vm.$nextTick(() => {
        //checking that my computed has changed, in my case I want to matchanObject
          expect(wrapper.vm.myComputedName).toMatchObject({
            'red--warning': true
          })
          //check what your computed value looks like
          console.log(wrapper.vm.myComputedName)
          done()
        })
      })

//TEST 2 Variant, this time instead red, lets say yellow

      it('computed return yellow if prop variant is red', async (done) => {
        const config = createConfig({ propsData: { variant: 'yellow' } })
        wrapper = shallowMount(test, config)
        wrapper.vm.$nextTick(() => {
        //checking that my computed has changed, in my case I want to matchanObject
          expect(wrapper.vm.myComputedName).toMatchObject({
            'yellow--warning': true
          })
          //check what your computed value looks like
          console.log(wrapper.vm.myComputedName)
          done()
        })
      })
    })

for more info, this page helped me.

https://vuejsdevelopers.com/2019/08/26/vue-what-to-unit-test-components/

The reason why the computed property didn't update, was because I created the id object of both this.favourite.selectedChoices.second and this.favourite.selectedChoices.first, after the component was rendered. Declaring the id objects before render was the solution.

Related