Let's say when a component loads I make an async request. That component also has a submit button that the user can press which triggers a function that relies on the result of that original request. How do I delay executing the triggered function until the async request is finished?
If that doesn't make sense let me give an example. MyComponent
makes an async request getRandomColor()
on mounted
. MyComponent
's template has <button @click="handleClick">
. handleClick
calls some function saveColor()
. How do I make sure that saveColor()
is not called until my async getRandomColor()
is finished?
I'm currently using Vue.js but I think this question applies to all of javascript.
CodePudding user response:
You can achieve this by adding :disabled
attribute in your button element. The value of :disabled
will be based on the response. i.e. If response will be there then enabled it otherwise disabled.
Working Demo :
const app = Vue.createApp({
el: '#app',
data() {
return {
buttonText: 'Call Me!',
apiResponse: [],
isDisabled: false
}
},
methods: {
saveColor() {
console.log('saveColor method call');
}
},
mounted() {
axios.get("https://jsonplaceholder.typicode.com/users").then(response => {
this.apiResponse = response.data; // Here we are getting proper response. hence, button is getting enabled.
}).catch((error) => {
console.warn('API error');
});
}
})
app.mount('#app')
<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<div id="app">
<button v-on:click="saveColor()" :disabled="!apiResponse.length">{{ buttonText }}</button>
</div>
Adding below snippet as per the comment added by the author of the post.
What if I didn't want to use the disabled button? Is there a way to make the button handler wait for the request to finish before it continues execution?
const app = Vue.createApp({
el: '#app',
data() {
return {
buttonText: 'Call Me!',
apiResponse: [],
isDisabled: false
}
},
methods: {
saveColor() {
console.log('saveColor method call');
}
},
mounted() {
axios.get("https://jsonplaceholder.typicode.com/users").then(response => {
this.apiResponse = response.data; // Here we are getting proper response. hence, button is getting enabled.
}).catch((error) => {
console.warn('API error');
});
}
})
app.mount('#app')
<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<div id="app">
<button v-on:click.prevent="apiResponse.length ? saveColor() : {}">{{ buttonText }}</button>
</div>