1

I am having a bit hard time understanding the following JS:

const store = new Vuex.Store({
  state: {
    todos: [
      { id: 1, text: '...', done: true },
      { id: 2, text: '...', done: false }
    ]
  },
getters: {
  // ...
  getTodoById: (state) => (id) => {
    return state.todos.find(todo => todo.id === id)
  }
}
})

store.getters.getTodoById(2) // -> { id: 2, text: '...', done: false }

These two code snippets are taken from official Vuex Documentation on Method Style Access for Getters.

Now what I dont understand is, how those the second part of code output the value in the comment? Maybe I miss-understood JS functions?

I believe the output would be:

(id) => {
  return state.todos.find(todo => todo.id === id)
}

So actually the second functions that is being returned, because in the call that they used, I do not see two '()()' nor do I understand from where does the function receive the 'state' variable.

I would kindly like to ask for an explanation, whether I miss-understood something in JS, or is this something Vuex specific?

user3533253
  • 39
  • 1
  • 8
  • It's a javascript thing. This answer is a good explanation: https://stackoverflow.com/a/32787782/11375753 – RonaldT Apr 22 '21 at 21:27

2 Answers2

3

See this for curried arrow function example: https://stackoverflow.com/a/32787782/11375753


However, when we take this in consideration with the vuex getter method it works as follows.

getters: {
  getTodoById: (state) => (id) => {
    return state.todos.find(todo => todo.id === id)
  }
}

  • We define a function in the property called getToboById.
  • And we define another function when the first one is called. In the example (id) => {}. This will take our argument.
  • The (state) part of the first declaration. If we take a regular getter without taking an argument. We always have access to the state argument. Vuex provides this for every getter function.
  • So when we call the following: store.getters.getTodoById(2). You are actually doing store.getters.getTodoById()(2). Where in the first function call you will already contain the state.

So, to conclude: This function call store.getters.getTodoById() will return us a function. Which we can call again with our argument.

And according to the linked example will look like:

  getTodoById: function(state) {
    return function(id) {
      return state.todos.find(todo => todo.id === id);
    }
  }
RonaldT
  • 338
  • 2
  • 10
-1

This involves "the currying of functions", to put it simply:

//①
const add = (x, y) => x + y;
add(2,3) // 5

The currying of this code will be:

//②
const add = x => y => x + y;

and turn it into ES5 code would be like this:

const add = function(x){

in that:

getters: {
    //...
    getTodoById: (state) => (id) => {
        return state.todos.find(todo => todo.id === id)
    }
}

It can be written as its equivalent (just like ② and ① are equivalent):

getters: {
    //...
    getTodoById: (state,id) => {
        return state.todos.find(todo => todo.id === id)
    }
}

The state parameter is the default parameter of getters, so you can call it like this:

store.getters.getTodoById(2);

refer:

https://stackoverflow.com/a/67221323/12261182

https://stackoverflow.com/a/32787782/11375753