I’m implementing on Vue JS with Inertia a list where you can filter by name
data() { return { selectedUser: this.value, selected: null, search: '', } }, computed: { userlist: function(){ return this.users.filter(function(user){ return user.name.toLowerCase().match(this.search.toLowerCase()) }); } },
and the component
<input class="form-input" placeholder="Search.." v-model="search"> <a href="#" class="block px-4 py-2 text-sm leading-5 text-gray-700 hover:text-gray-900 hover:bg-gray-100 focus:outline-none focus:bg-gray-100 focus:text-gray-900 flex items-center" v-for="user in userlist" :key="user.id" @click.prevent="select(user)">
However, when I open the modal, where the component is, I get an error
Uncaught (in promise) TypeError: Cannot read property 'search' of undefined
I’ve already hardcoded the search value, like this
computed: { userlist: function(){ return this.users.filter(function(user){ return user.name.toLowerCase().match('John') }); } },
and the component renders just fine. I’m not getting where the error could be, so any help would be appreciated
Advertisement
Answer
The problem PROBABLY is that you’re using the this
keyword expecting it to be a reference to your component instance, but you’re using it inside a function
declaration, which creates a new context, causing this
to be undefined
.
computed: { userlist: function(){ // here, this is the component instance return this.users.filter(function(user){ // --> function(user) { creates a new context // here, this is undefined and this.search will cause the error return user.name.toLowerCase().match(this.search.toLowerCase()) }); } }
To prevent this, you can use an arrow function, which will will keep the existing context. This means that the this
keyword will still reference your component instance.
computed: { userlist: function(){ // here, this is the component instance return this.users.filter((user) => { // --> replaced function with an arrow function // here, this is still a reference to the component instance return user.name.toLowerCase().match(this.search.toLowerCase()) }); } }