VueJs Disable anchor link while processing an async function

1.8k views Asked by At

I have the following element in my list.vue file:

<a id="anchorLink"
    class="button is-primary is-fullwidth-mobile mb-sm"
    @click="functionA()">
    <span>Call Function A</span>
</a>

And this is the function functionA

async functionA() {
  // do something
},

All I want to do is disable the anchor link until functionA processing is done, then only enable back the link.

So i tried all these options to disable it but no luck so far:

OPTION01:

async functionA() {
document.getElementById('anchorLink').disabled = true;
// do something
}

OPTION02: using .prevent

<a id="anchorLink"
    class="button is-primary is-fullwidth-mobile mb-sm"
    @click.prevent="functionA()">
    <span>Call Function A</span>
</a>

OPTION03: using v-on:click.prevent

    <a id="anchorLink"
    class="button is-primary is-fullwidth-mobile mb-sm"
    v-on:click.prevent="functionA()">
    <span>Call Function A</span>
</a>

I don't get any console error when I tried all the options, but it still doesn't do the job.

Can someone please help me out here.

2

There are 2 answers

0
Mohammad Basit On BEST ANSWER

Keeping the code that you have provided in consideration. As far I understand your question you can disable the <a> link by assigning dynamic classes by binding it to data property of the class like :class to your anchor tag. Use object based class syntax for your <a> tag and then toggle the class name with a boolean value.

Note: The Link will turn red in color when it is in disable phase and when function execution is complete it will turn back to it's original color. While it is red you won't be able to execute functionA()

TEST IT HERE

Your vue markup

<template>
 <div id="app">
 <a id="anchorLink"
  :class="{ isDisabled: !call }"
  @click="functionA">
  <span>Call Function A</span>
 </a>
 </div> 
</template>

Vue Class

export default {
 name: 'App',
 data: () => ({
   call: true
 }),
 methods: {
  async functionA(){
   if (this.call) {
    this.call = false;
    console.log('running function')
    setTimeout(()=> {
      this.call = true // mimic function execution behaviour using setTimeout here
    }, 2000)
   }
  }
 }
} 

CSS

The pointer-events property defines whether or not an element reacts to pointer events. Not necessary to add but you can include it.

.isDisabled {
  pointer-events: none;
  color: red
}

Hope it helps!

0
Ezra Siton On

It's hard to answer specific to your Q (Your code example is not complete).

Anyway, this is +- "hello world" of the idea (wait for a Promise than do something).

Vue.config.devtools = false;
Vue.config.productionTip = false;

new Vue({
  el: '#app',
  data: () => ({
    terms: true
  }),
  computed: {
    isDisabled: function(){
      return !this.terms;
    }
  },
  methods: {
    async disable_for_2_seconds() {
      try {
        this.terms = !this.terms;
        const msg = await hello_Promise();
        this.terms = !this.terms;
        console.log('Message:', msg);
      } catch(error){
        console.error(error);
      }
    },
  },
})

function hello_Promise() {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve('Function A - Time Ends! Enable button');
    }, 2000);
  });
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <h3>Async/Await</h3>
  <button :disabled='isDisabled' v-on:click="disable_for_2_seconds">Disable Button for 2 seconds on click</button>
  <br>Disable: <b>{{isDisabled}}</b>
</div>

Disable/Enable button related Stackoverflow Q: how-to-disable-button-in-vuejs

Related JS docs: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function