Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

VueJS: variable is undefined inside computed only

Tags:

I'm trying to make async autocomplete input with Vue, Nuxt, Axios and Buefy. It basically works, but I need to have different strings when user just starts typing and there's yet nothing to show, and when there is nothing found for such request.

I'm checking in computed variable if input value isn't empty and axios returns empty array to handle if the request address cannot be found. But it causes error

Cannot read property 'length' of undefined

The weird thing is that address variable is successfully used in other parts of my component.

My vue file below:

<template lang="pug"> b-field(label="Your address?")     b-autocomplete(     rounded,     v-model="address",     :data="data",     placeholder="Start typing",     icon="magnify",     @input="getAsyncData",     @select="option => selected = option",     :loading="isFetching"     )         template(slot="empty") {{ dummyText }} </template>  <script> import axios from 'axios' import debounce from 'lodash/debounce'  export default {     data() {         return {             data: [],             address: '',             selected: null,             isFetching: false,             nothingFound: false,             test: false         }     },      computed: {         dummyText: () => {             if (this.address.length > 0 && this.nothingFound) { // This will return error                 return 'There is no such address'             } else {                 return 'Keep typing'             }         }     },      methods: {         getAsyncData: debounce(function () {             this.isFetching = true              axios.post('https://suggestions.dadata.ru/suggestions/api/4_1/rs/suggest/address', {                 "query": this.address,                 "count": 8             }, {                 headers: {                     'Authorization': 'Token sometoken',                     'Content-Type': 'application/json',                     'Accept': 'application/json',                 }             })                 .then(response => {                     this.isFetching = false                     this.data = Object.values(response.data.suggestions)                     if (response.data.suggestions.length===0) this.nothingFound = true                     console.log(this.address.length) // This will work                 })                 .catch(error => {                     this.isFetching = false                     console.log(error);                 })         }, 300)     } } </script> 

This is not about ssr, I've tried to init component inside mounted hook. Think I'm missing out something obvious, but I've already spent hours trying to fix this without success

like image 820
Elijah Ellanski Avatar asked May 09 '18 18:05

Elijah Ellanski


2 Answers

Don't use arrow function ()=>{} for computed, it will cause the wrong context (not current Vue instance).

Change to function () {} then it should work fine.

And for methods, watch, you should follow same rules.

computed: {     dummyText: function () { // change to function () {}         if (this.address.length > 0 && this.nothingFound) { // This will return error             return 'There is no such address'         } else {             return 'Keep typing'         }     } }, 
like image 61
Sphinx Avatar answered Oct 23 '22 12:10

Sphinx


You can also use es2015 shorthand for a method function:

computed: {     dummyText() {         return this.address.length > 0 && this.nothingFound ? 'There is no such address' : 'Keep typing';     } } 
like image 43
Artem Gorlachev Avatar answered Oct 23 '22 11:10

Artem Gorlachev