Fix this is Undefined in Vue

John Au-Yeung
May 12 · 4 min read
Image for post
Image for post
Photo by Igor Peftiev on Unsplash

Vue.js is an easy to use web app framework that we can use to develop interactive front end apps.

In this article, we’ll look at how to fix the ‘this is undefined’ error in Vue apps.

How to the Error Shown?

How to fix “this is undefined”?

Arrow functions do not bind to this , which we need to access the Vue component instance.

For instance, if we have the following code:

index.js :

new Vue({
el: "#app",
data: {
text: "foo"
},
methods: {
toggle: () => {
this.text = this.text === "foo" ? "bar" : "foo";
}
}
});

index.html :

<!DOCTYPE html>
<html lang="en">
<head>
<title>App</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<button @click="toggle">Toggle</button>
<p>{{text}}</p>
</div>
<script src="index.js"></script>
</body>
</html>

Then our code won’t do anything as the text field return from data isn’t updated. We can fix this by replacing the arrow function with a regular function as follows:

new Vue({
el: "#app",
data: {
text: "foo"
},
methods: {
toggle() {
this.text = this.text === "foo" ? "bar" : "foo";
}
}
});

Therefore, we should try to avoid using arrow functions on Vue components, if they need to reference this .

We can still use arrow functions for functions that we call inside a top-level function and we need to access this , which is the Vue component instance.

We may use arrow functions as callbacks for other functions that we call inside methods. For instance, if we want to filter something in a method, we may write the following code:

new Vue({
el: "#app",
data: {
name: "",
names: ["foo", "bar", "baz"]
},
computed: {
filteredNames() {
if (!this.name) {
return this.names;
}
return this.names.filter(n => this.name === n);
}
}
});

index.html :

<!DOCTYPE html>
<html lang="en">
<head>
<title>App</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<input v-model="name" />
<p v-for="n in filteredNames">{{n}}</p>
</div>
<script src="index.js"></script>
</body>
</html>

In the code above, we have a computed property that returns the filtered names according to what we type into the input, which is bound to the name property.

We can use an arrow function in the filter callback because we’re referencing the this which is already bound in the filteredNames function.

Therefore, we already have the right value of this , which comes from the filteredNames function. In the arrow function, the value of this is taken from whatever is set as the value of this outside the arrow function is invoked.

An arrow function is shorter and more concise, so readability is improved, and we can use this from the surrounding context without setting it to another variable first.

Image for post
Image for post
Photo by Quentin Dr on Unsplash

Fetching Data

For instance, we can write:

index.js :

new Vue({
el: "#app",
data: {
joke: { value: {} }
},
mounted() {
fetch("https://api.icndb.com/jokes/20")
.then(res => res.json())
.then(data => (this.joke = data));
}
});

index.html :

<!DOCTYPE html>
<html lang="en">
<head>
<title>App</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<p>{{joke.value.joke}}</p>
</div>
<script src="index.js"></script>
</body>
</html>

In the code above, we used arrow functions to set this.joke to data . We can do this because we need the this from the Vue component instance, this.joke references the joke property of data .

Lexical Scoping

As we can see from the examples above, this in an arrow function is determined by whatever it’s located outside of the function.

Regular functions sets this to their own value, which is the function itself. Therefore, if we don’t need to reference this or only need to reference this which is outside the function, then we arrow functions.

Conclusion

The Startup

Medium's largest active publication, followed by +733K people. Follow to join our community.

John Au-Yeung

Written by

Web developer. Subscribe to my email list now at http://jauyeung.net/subscribe/. Email me at hohanga@gmail.com

The Startup

Medium's largest active publication, followed by +733K people. Follow to join our community.

John Au-Yeung

Written by

Web developer. Subscribe to my email list now at http://jauyeung.net/subscribe/. Email me at hohanga@gmail.com

The Startup

Medium's largest active publication, followed by +733K people. Follow to join our community.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store