VueJS is a great micro frontend framework for building single-page applications. However, one serious limitation struck me today, that will probably stop me from using the framework for any serious project from now on.

Specificifically, the fact that you can not use arrow functions (ES syntax) if you declare a VueJS method that reads or writes to one of the Component’s data properties (a very common scenario).

For example, let’s imagine you have a component that does 2 things: it has a form with a single text input and a button to trigger a search based on the text input value (think of it like the Google homepage). The value of the text input is usually stored as a data property within the component, through model binding (v-model="attribute-name-here"). As you press the button, you trigger a method within the component that is supposed to “read” that attribute and make an API call (e.g. using the axios library) and pass that value to the API. The API responds with some values that you may also want to map as data attributes of the component. Both of these things – you can not do, if you use the arrow syntax for the method.

The reason is – arrow syntax changes the this context and it no longer refers to the Vue component itself. This effectively means that the following example is not possible:

    export default {
        name: 'HelloWorld',
        data: () => ({
            url: '',
        }),
        methods: {
            someMethod: () => {
                // Make an API call to retrieve some data by using a component data attribute
                axios
                    .post('http://0.0.0.0:8081/api/link', {
                        // Try to get a component data variable
                        // This results in a "trying to get a property of undefined" error
                        // because "this" doesn't refer to the HelloWorld component
                        url: this.url
                    })
                    .then(() => {
                        // Do something with the response
                    });
            }
        }
    }

The solution is simple – replace the someMethod definition from an arrow function to a regular function(){}. This doesn’t really make sense in the modern frontend development age though and is not something for Vue to enforce. Arrow functions are the future and I shouldn’t be forced to use a mixture of ES and non-ES syntax, just because I rely on some framework (VueJS).

You can read more about the reasoning why this happens in the Vue documentation. Here’s an excerpt:

Don’t use arrow functions on an options property or callback, such as created: () => console.log(this.a) or vm.$watch(‘a’, newValue => this.myMethod()). Since an arrow function doesn’t have a this, this will be treated as any other variable and lexically looked up through parent scopes until found, often resulting in errors such as Uncaught TypeError: Cannot read property of undefined or Uncaught TypeError: this.myMethod is not a function.

https://vuejs.org/v2/guide/instance.html#Instance-Lifecycle-Hooks

What’s your thought on that? Have you bumped into the same limitation? Is there an easy workaround or you just “get along” and consider this an acceptable thing?

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.