0

I am new to Vue. I would like to know how many times a function in computed has been called, so I wrote this component:

const ComputedCounter = {
    name: "ComputedCounter",
    template: `
        <span>{{ value }}</span>
    `,
    computed: {
        value() {
            const current = this.value || 0;
            return current + 1;
        }
    }
}

However, 'Error in render: "InternalError: too much recursion"' error is thrown. I am confused, what is happening here and is there a way to make this work?

1

4 Answers 4

1

If you read the documentation:

A computed property will only re-evaluate when some of its reactive dependencies have changed.

That means if your value this.value changes then your computed propertie will be executed. But the problem is if you execute your computed propertie you change value. Now because value has changed you execute again your computed propertie and because of that value has changed witch leads again to that your computed propertie gets executed again and so on i hope you get it.

Sign up to request clarification or add additional context in comments.

3 Comments

Ok, now I understand why the issue happens, but I can't come up with a way to do what I was trying to do.
@TomášČerný What are you trying to do?
This answer doesn't explain properly why the recursion is happening, it's not because the value of the computed changes, it's because the computed has a dependency on itself, so it is calling itself infinitely and can never return
0

I don't see stop condition in your recursion
too much recursion is equivalent to maximum call stack size exceeded
so this is js issue not with vue

1 Comment

Could you indicate with code what you mean? As far as I know, this.value doesn't reference computed.value function.
0

In your data, set:

_value: 0

then you can refer to this._value inside your value() method:

value() {
    return this._value++;
}

Comments

0

You are trying to know how many times a computed has been called, which is possible in itself, your issue is that both your counter for how many times it's been called and the computed have the same name, which doesn't make too much sense

This results in your computed having a dependency on itself, which calls itself infinitely (the name of the computed is value and you reference this.value in it)

This would result in the following stack trace where the computed never returns a value

// From template
this.value()
// From the computed
this.value()
// From the computed
this.value()
// From the computed
this.value()
// Infinitely

To achieve your count, you would need a differently named variable like this

const ComputedCounter = {
    name: "ComputedCounter",
    template: `
        <span>{{ computedValue }}, computedValue has been called {{ counter }} times</span>
    `,
    data() {
      return {
        counter: 0,
        value: 0,
      };
    },
    computed: {
        computedValue() {
           this.counter++; // Side effects in computed are higly discouraged and for any other case, you should use a watcher
           return this.value;
        }
    }
}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.