Search code examples
vue.jsvuejs3conditional-operatorref

How do I combine refs in Vue.js with a ternary expression?


Consider the code snippet below:

const salesFilter = computed(() => {
  return Object.values(dataset.value).filter((item) => item.category==="Sales")
})
const salesTotalTwo = ref((salesFilter.value.length == 0) ? []:salesFilter.value[0].values)

When the app gets mounted, dataset is empty, so salesFilter returns empty as well. In that case, I want salesTotalTwo to return an empty list, but I'd like it to be updated the moment dataset starts containing some information. When I run tests, I can see that salesFilter behaves as expected, but for some reason salesTotalTwo keeps referring to an empty list. Is my approach of combining a ref with a ternary expression just wrong? Is there a smarter way to do this?


Solution

  • It's happening because salesTwo property is not reactive. You need to make it using a computed property.

    Here is a demo-

    const { createApp, ref, computed } = Vue
    
    const app = createApp({
      setup() {
        const dataset = ref([]);
        const salesFilter = computed(() => {
          return Object.values(dataset.value).filter((item) => item.category === "Sales")
        })
        const salesTotalTwo = computed(() => {
          return salesFilter.value.length == 0 ? [] : salesFilter.value[0]
        })
        const setDataset = () => {
          dataset.value.push({
            category: "Sales"
          })
        }
        return {
          dataset,
          salesFilter,
          salesTotalTwo,
          setDataset
        }
      }
    }).mount('#app')
    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
    
    <div id="app">
      salesTotalTwo - {{ salesTotalTwo }} <br>
      <button @click="setDataset">Set dataset</button>
    </div>