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
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'
}
}
},