Update a property from a callback - vuejs2

I am trying to use a function from a library that is called like this
convertString(input, options, callback)
Having a simple template like the following
<template>
<textarea v-model="inputText"></textarea>
{{ convertedText() }}
</template>
I tried the following
export default {
data () {
return {
inputText: ''
}
},
methods: {
convertTextCallback: function (err, result) {
if (!err) return result
},
convertedText: function () {
options = ''
convertString(this.inputText, options, this.convertTextCallback)
}
}
}
The problem is that the convertedText function needs to return a string but the string is generated when the callback runs. How can I return the string generated from the callback.

You could use async/await however using asynchronous calls in this way is discouraged. I recommend using a watcher and another data property.
First of all, I believe that the setup you provided would not do what you want it to even if it was not asynchronous. It will call converted text on page load when input text is empty and this will then not update as it is not a computed property.
A working example:
export default {
data () {
return {
inputText: '',
result: '',
}
},
methods: {
convertTextCallback: function (err, result) {
if (!err) this.result = result
},
},
watch: {
inputText: function() {
options = ''
convertString(this.inputText, options, this.convertTextCallback)
}
}
}
And then in your template
<template>
<textarea v-model="inputText"></textarea>
{{ result }}
</template>

Related

getter/state are not calling on initial time vuejs

I am trying to return a function into computed property but on page refresh getter or state does not load the data into computed property. How can I resolve this ? I did try async await into computed property too it doesn't work. Please guide.
export default {
data(){
return {
isLoading: false,
}
},
async created(){
await this.profile()
},
methods: {
async profile(){
this.isLoading = true;
return await Promise.all([
this.$store.dispatch('class'),
this.$store.dispatch('list')
]).finally(() => {
this.isLoading = false;
})
}
},
computed: {
getItem() {
console.log(this.$store.getters); //This records did not load at first time after rerouting it does work
return () => this.$store.getters.listItem;
}
}
}
I can't figure out why you need to return a function from the computed value.
However, using the computed value in your template will work.
<template>
<div>
{{ getItem() }}
</div>
</template>
But if you want to see your console log, you can use a local variable to force the Vue to watch changes.
computed: {
getItem() {
const lst = this.$store.getters.listItem;
console.log(lst);
return () => lst;
},
},
I think it is better to use the store value directly.
computed: {
getItem() {
return this.$store.getters.listItem;
},
},

How to delete Vuex store when the user sign out

I want to get an object from Vuex store and I want to display it. So this is how I am trying to display:
<div v-if="authenticated">
Hello, {{ getUser.attributes.first_name }}
</div>
And here is my logic:
mounted() {
if (authHelper.validAuthentication()) {
this.getUser();
}
EventBus.$on(GENERAL_APP_CONSTANTS.Events.CheckAuthentication, () => {
this.authenticated = authHelper.validAuthentication();
});
},
computed: {
getUser() {
return this.$store.state.user;
}
},
So as it is seen if the authentication is true I want to get the user object from the Vuex store. But I am getting this error: TypeError: this.getUser is not a function
Use methods instead of computed.
methods: {
getUser() {
return this.$store.state.user;
}
},

Vue2 set a variable from an api callback

I have this function return a call back as:
function fetchShifts(ctx, callback) {
const accountId = selectedAccount.value.value.id
store.dispatch('app-action-center/fetchShifts', {
accountId,
})
.then(shifts => {
const data = []
shifts.forEach(async (shift, index) => {
const user = await store.dispatch('app-action-center/fetchUserDetails',
{
assignedTo: shift.assignedTo,
})
.then(res => res)
data.push({
...shift,
user: user.fullName,
})
if (index === (shifts.length - 1)) { callback(data) }
})
})
}
In the vue file I try to set it as:
data() {
return {
shifts: this.fetchShifts,
}
},
or
data() {
return {
shifts: null,
}
},
created() {
this.shifts = this.fetchShifts()
}
None of them work, I want to make this shifts variable ready when the component mounted so I can put it in the <app v-for="shift in shifts" />
At this moment, this code work fine with <b-table :items="fetchShifts /> but I don't know how to convert to <ul v-for="shift in shifts></ul>
Try like this:
<ul v-for="shift in shifts" :key="shift.id">
</ul>
export default
{
data()
{
return {
shifts: [],
};
},
created()
{
this.fetchShifts(undefined, (shiftsArray) =>
{
this.shifts = shiftsArray;
});
}
}
Explanation - initially you start with an empty array. Then you asynchronously fetch the shifts. The callback is called as soon as all the shifts and the corresponding users have been fetched - and in this callback you update the array with the shifts, which in turn triggers component re-rendering.
Vue is truly amazing!

Calling API in method and getting [object Promise]

I'm using Nuxt.js in static site mode, and trying to get an image from an API using a string passed in a prop, however, in the template I am getting [object Promise]. I would've thought that return before the get request would resolve the promise, but I think my grasp of promises and Nuxt.js a little off. Any help would be greatly appreciated.
<template>
<div>
{{ getThumbnailSrc() }}
</div>
</template>
<script>
import axios from 'axios'
export default {
props: {
link: {
type: String,
required: true
}
},
data() {
return {
imageUrl: null
}
},
methods: {
getVimeoId(link) {
return link.split('/').pop()
},
getThumbnailSrc() {
return axios
.get(
`https://vimeo.com/api/v2/video/${this.getVimeoId(
this.link
)}.json`
)
.then(response => {
const vimeoThumbnailUrl = response.data[0].thumbnail_large
console.log(vimeoThumbnailUrl)
return {
vimeoThumbnailUrl
}
})
.catch(error => {
console.log(error)
})
}
}
}
</script>
It sure won't! XHR requests are asynchronous and therefore the template has no idea that it needs to wait.
Solve it by using an additional data property on the component, and using that instead:
data() {
return {
imageUrl: null,
thumbnailSrc: null
}
},
And in your callback:
.then(response => {
const vimeoThumbnailUrl = response.data[0].thumbnail_large
console.log(vimeoThumbnailUrl)
this.thumbnailSrc = vimeoThumbnailUrl
})
Now you can use {{thumbnailSrc}} and it will load appropriately.

Access vue instance from handsontable

I am trying to set a vuejs variable from within handsontable.
The vuejs variable:
this.dataChanged
in code block below is not available from handsontable settings, any idea how can I access it?
<template>
<div id="hot-container">
<HotTable :root="root" :settings="hotSettings"></HotTable>
</div>
</template>
<script>
export default {
data() {
return {
#vuejs variable i want to set from hot
dataChanged: false,
root: 'test-hot',
hotSettings: {
data: [{something: 0}],
afterChange: function(changes, src) {
if (src !== 'loadData') {
this.dataChanged = true
}
},
methods: {
saveChanges: function () {
if (this.dataChanged){
//save data
}
}
}
I faced this same problem... I found a workaround posted on GitHub like so..
This way you can access all Vue's data, methods, etc as you normally would.
data() {
return {
hotSettings: {
...
afterChange: this.afterChangeVue
...
}
}
},
methods: {
afterChangeVue(changes, source) {
console.log('changes, source => ', changes, source);
console.log('this.$store => ', this.$store);
},
Here is the link to the original thread: https://github.com/handsontable/vue-handsontable-official/issues/7#issuecomment-356190395
I ended up saving to a variable declared outside of vue - ie above the data () declaration
var myNewVar = 42
data() {
#can save to myNewVar from here
Just like #Rosdi_Kasim said, but much simpler with fat arrow function
data() {
return {
hotSettings: {
/*...*/
afterChange: (changes, source) => {
console.log('changes, source => ', changes, source);
console.log('this.$store => ', this.$store);
}
/*...*/
}
}
},
methods: {
}