Search code examples
vue.jsvuexvue-router

How can I determine state based on whether or not it's coming from a route param or a mutation?


I need to get a record in multiple places outside of my record component and am using Vuex and a mounted call tho get the record:

Vuex

state: {
    record: null,
    loaded: false,
    currentRecordId: null
  },
  mutations: {
    SET_CURRENT_RECORD_ID(state, recordId){
      state.currentRecordId = recordId
    }
  },
  actions: {
    getRecord(context){
        axios.get('api/thought'+this.state.currentRecordId)
          .then(response => {
            context.commit('SET_RECORD_DATA', response.data.data)
          })
          .catch(error => {
            
          })
    }
},

Record Component

mounted() {
    this.getRecord()
},

methods: {
    getRecord: function(){
        this.$store.dispatch('getRecord');
    },
}

The problem is that sometimes the currentRecordId state will need to come from a route parameter this.$route.params.hashedId and sometimes it will be set by the SET_CURRENT_RECORD_ID() mutation. The reason being is the record needs to be gotten from various modals and other components. For example:

Records Component

<template>
<div v-for="record in records">
    <button><span @click="setRecordHashedId(record.id)" class='bg-blue'> <v-icon class="mr-1">launch</v-icon> View/add details</span></button>
</div>
</template>

<script>
    export default {
        data: function() {
           return {
                records: null,
           }
        },
        mounted() {
            this.getRecords()
        },
        methods: {
            setRecordHashedId(hashedId) {
                this.$store.commit('SET_CURRENT_RECORD_ID', hashedId);
                this.$router.push({ name: 'record', params: {hashedId: hashedId } })
            }
        }
    }
</script>

So how do I determine in Vuex if the currentRecordId is coming from a route param or a mutation?


Solution

  • Why not use a payload parameter in your action for the ID, falling back to the one in your state if it's not set?

    actions: {
      getRecord: async ({ commit, state }, recordId) => {
        const url = `api/thought${encodeURIComponent(recordId ?? state.currentRecordId)}`
        const { data: { data } } = await axios.get(url)
        commit('SET_RECORD_DATA', data)
      }
    }
    

    Then you can dispatch either way

    this.$store.dispatch("getRecord") // use state.currentRecordId
    // or
    this.$store.dispatch("getRecord", this.$route.params.hashedId)
    

    If your environment doesn't support the null coalescing operator (??), try this legacy option

    recordId = typeof recordId !== "undefined" ? recordId : state.currentRecordId
    const url = `api/thought${encodeURIComponent(recordId)}`