Skip to content

Vuex documentation enhancement - return functions in getters #598

@mudrz

Description

@mudrz

Request for enhancing the documentation

This has been discussed in several other Issues (for example #526 and #456), and as someone who is learning Vue + Vuex who just went through the same issue, it would be very helpful to have such common cases in the official docs, instead of in the closed issues

Accessing array data is not an isolated use-case, but instead an absolute necessity for larger applications

Reasoning below (if there is another, better Vuex way, please share it) vuex is playing the role from one side as a simple abstraction of the application data
//the state, similar to the DBContext layer in the ORM world
const state = {
    products = [
          { id:1, fullName:'foo', price: 200, color: 'red' },
          { id:2, fullName:'bar', price: 999, color: 'blue' }
    ]
}
//and the abstraction over direct data access, similar to the DBSets in ORMs
const getters = {
    products(state){
      return state.products
    },
    //or simply
   products: state=> 
}

But also as a repository pattern substitute, where data changes are done through mutations.

const mutations = {
     //addProduct(state, payload)
     addProduct(state, { fullName, price, color }){
        state.products.push({
            fullName,
            price,
            color,
            id: generateProductId()
        })
     }
}

In that sense, I felt that Vuex is in an odd spot (I was comparing Vuex with a standard data repository pattern) where data changes are abstracted within the scope of vuex (mutations), but data getting of array items is supposed to be carried out by a separate application layer, instead of having commonly used getters with arguments:

const dynamicGetters = {
     getProductById: (state, getters, payload) => {
      return getters.products.find(x=> x.id === payload)
    },

     getProduct: (state, getters, { name, color }) => {
      return getters.products.find(x=> x.fullName === name && x.color === color)
    }
}

so that queries used from different parts of the application can be cached in a centralized location (the ORM/DB way of thinking, obviously not valid in the Vue + Vuex world) and only specific, non-standard queries are moved to their own layer

It is fairly obvious that getters can return functions once you see it, but not so much when you have OOP background

Hopefully this helps others - the upper dynamicGetters (these don't exist in vuex) represented as standard getters that return functions, as suggested by @ktsn :

const getters = {
    //ES6
    getProductById: (state, getters) => (id) =>{
           return getters.products.find(x=> x.id === id)
    },
   //function syntax
   getProductById: function(state, getters){
      return function(id){
           return getters.products.find(x=> x.id === id)
        }
    },
     getProduct: (state, getters) => ( { name, color } ) {
      return getters.find(x=> x.fullName === name && x.color === color)
    }
}
//and then used in the vue instance (state and getters get automatically injected)
//where preferably the output product should be a computed property instead of direct methods
let product1 = this.$store.getters.getProductById(2)
let query = {
 name: 'foo',
 color: 'red'
}
let product2 = this.$store.getters.getProduct(query)

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentationenhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions