Vue.js "this is undefined" error in javascript array filter and functions


How to fix "this is undefined" error in Vue.js, Javascript array filter

While you were coding your front end app, suddenly an strange error started pulling your head  "this is undefined"?  if so don't worry ! you are not alone, I have seen this error countless number of times. Primary reason for the error is, that you are trying to refer the Vue instance when the  context of  "this" is lost.

I have two select field in my app, one is course subject and the other one is programs list, the program list drop-down get populated when my user select a particular item in the course subject drop-down. 

Have a look at the following piece of code:

var app = new Vue({
    el : '#app',  
    data: {       
        program_list: [],
        subject: 1
    },
    computed: {
        filteredPrograms: function() {          
            return this.program_list.filter(function(program){
                return program.subjectId == this.subject;
            };
        }
    }
});

I hope the previous code block should be straight forward. If you looked at the code, there are two data property, one for selected subject and other one is an array of object that contains all the programs, I am using a Vue computed property "filteredPrograms" that must always contain only the programs under the selected subject. However this code is   giving me an error "this is undefined" in my browser console.

The reason behind the error is, when we try to access "this" inside a function which is being passed as an argument to the filter method as in the example above, the context of Vue instance is lost, therefore the "subject" property in the Vue instance is not accessible in this case. 

This problem can be solved in 3 possible ways:

1. Using Arrow Function

filteredPrograms() {
  return this.program_list.filter((program) => {
    return program.subjectId === this.subject;
  });
}

2. Using .bind()  method:

filteredPrograms() {
  return this.program_list.filter(function(program) {
    return program.subjectId === this.subject;
  }.bind(this));
}

3. Using a local variable outside the filter function:

filteredPrograms() {
  let vm = this;
  return this.program_list.filter(function(program) {
    return program.subjectId === vm.subject;
  });
}

While you can solve the issue with any of the above possible ways, the option1 is not compatible with internet explorer (ie), ie browser doesn't support arrow functions. So I recommend using either option2 or option 3.

Written by Akram Wahid 4 years ago

are you looking for a chief cook who can well craft laravel and vuejs, to make some awsome butterscotch,
yes then it is right time for you to look at my profile.

Do you want to write Response or Comment?

You must be a member of techalyst to proceed!

Continue with your Email ? Sign up / log in

Responses

Be the first one to write a response :(

{{ item.member.name }} - {{ item.created_at_human_readable }}

{{ reply.member.name }} - {{ reply.created_at_human_readable }}