1

I am trying to find fibonacci sequence using state and a recursive action in vuex. Basically what I am trying here is rewrite this Javascript recursive function with vuex.

function fib(n) {
  if (n < 2){
    return n
  }
  return fib(n - 1) + fib (n - 2)
}

However, even if I am assigning the state to the action, the state's value never change. How can I make it work? I mean... I am struggling with this for a few days, so if you could give me some tips, or ideas, it would really helps.

Thanks. and this is my code below.

import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

export const store = new Vuex.Store ({
    state: {
        number: 8
    },
    mutations: {
        showTheNumber: (state) => {
            return state.number
        }
    },
    actions: {
        findFibNum: ({ dispatch, commit, state }) => {
            if (state.number < 2) {
                return state.number
            } else {
                dispatch('findFibNum', state.number - 1) + dispatch('findFibNum', state.number - 2)
            }
            return commit('showTheNumber')// I am not sure if it is redundant 

        }
    }

and this is how I am calling and showing the value of store in the component.

<template>
    <div>
        <input @input="addUserInput"></input>
        <p>Counter is: {{ counter }}</p>   
    </div>

</template>

<script>
    export default {
        methods: {
            addUserInput () {
                this.$store.dispatch('findFibNum')

            }
        },
        computed: {
            counter(){
                return this.$store.state.number;
            }
        }
    }
</script>

Nagisa Ando
  • 285
  • 5
  • 19
  • Even if you guys can not answer the question, if you could tell me how to make recursive work in vuex helps. Thanks a lot! – Nagisa Ando Jun 19 '20 at 17:34
  • It looks to me that the number never gets mutated and will always remain 8. This means that findFibNum() will always be calculating using 7 (state.number-1) and 6 (state.number-2). If that's the case, try updating the number using another mutation. – Vimona Jun 19 '20 at 19:57
  • Your code doesn't seem right. There is no code that is mutating the state number. The code you have in mutations is actually acting like a getter, it's not mutating anything. – Maarten Veerman Jun 20 '20 at 17:47

1 Answers1

0

You need an additional parameter in findFibNum and you also need to capture user input. Also, I would use @change instead of @input, because @input captures every key press and I don't think you want that. Actions are async in vuex, so you need to return a promise (see this answer). I think you want something like this

import {createStore} from 'vuex'

export default createStore({
    state:{
        number: -1
    },
    getters: {
        fibNumber: (state) => {
            return state.number
        }
    },
    mutations: {
        updateNumber: (state, newNumber) => {
            state.number = newNumber
        }
    },
    actions: {
        findFibNum: ({dispatch, commit, state}, number) => {
            return new Promise( (response,reject) => {
                if (number < 2) {
                    return response(number)
                }
                dispatch('findFibNum', number - 1).then(a => {
                    dispatch('findFibNum', number - 2).then(b => {
                        return response(a+b)
                    })
                })
            })
        }
    }
})

And this is my component

<script >
export default {
    data() {
        return {
            userInput: -1
        }
    },
    methods: {
        addUserInput (event) {
            this.$store.dispatch('findFibNum', event.target.value)
            .then(number => {
                this.$store.commit('updateNumber',number)
            })
            this.userInput = event.target.value
        },
    },
    computed: {
        fibNumber(){
            return this.$store.getters.fibNumber
        }
    }
}
</script>

<template>
    <div>
        <input @change="addUserInput($event)"> <!-- Input doesn't need a closing tag -->
        <p v-if="fibNumber > -1">The {{ userInput }}-th fibonacci number is: {{ fibNumber }}</p>   
    </div>
</template>

Note that you don't actually need to do this in vuex, all of this can be done in a vue component and is way easier.