[Vuejs]-Returning arrow function from Vuex storage getter: Not understanding

0👍

Let me see if I understand your doubt.

productIsInStock is a getter, that returns an arrow function, and vue evaluates this in the render function, through the template part:

<button
     @click="addProductToCart(product)"
     :disabled="!productIsInStock(product)">
       Add product to cart
</button>

It’s important first to understand that vue, thanks to :disable databind, evaluates the value as javascript. So it calulates the actual value of the getter (that is a function), and YOU call the actual return value (remember, is a function) that return something.

Put on another way: The getter are called everytime that related state changes, to recalculate the value, that is why you use the getter (like in this.getterA + this.getterB) and not CALL the getter (like this.getterA() this.getterB()).

If you still don’t understand, check my “fake” render function that replaces the template rendering:

let productIsInStock = () => product => { ... }

render(h) {
 return h('button', {
   '@click': () => this.addProductToCard(product),
   ':disabled': () => productIsInStock()(product), // using arrow fn instead of the getter
 }
}

This is also know as currying in functional programming language.

0👍

You define getters in your store as a function. This function is called with the state, other getters (and in case of module also the root state and root getters). Based on that you return some value. Normally, that data is some value (e.g. an object, number, boolean, etc.)

getters: {
  numberOfPolarBears (state) {
    return state.polarBears.length;
  }
}

Functions in javascript do not differ much from other data. A function like this can also be defined as some variable.

// Method 1
function ticklePolarBear (bear) {
  bear.tickle();
}

// Method 2
var ticklePolarBear = function (bear) {
  bear.tickle();
};

In either case, you would call it with:

ticklePolarBear(frostyTheBear);

Why is this important? While when you normally map a getter and that way get some data back, nothing prevents you from mapping a getter and returning a function that you can call later.

getters: {
  namedPolarBear (state) {
    return function (index) {
      if (index >= state.polarBears.length) {
        return null;
      }

      return state.polarBears[index].name;
    }
  }
}

The arrow function sets the context of this differently, but is otherwise very similar to the example above.


computed in a component provides (in this case) a getter function for some attributes. In your example, it returns what the getter in your store returns, namely a function. Since it is a function, you can call it.

In this case no reactivity is going on, so you could also write the following:

data () {
  return {
    productIsInStock: this.$store.getters.productIsInStock
  };
}

Leave a comment