1

I have a QR code creating page. I want my QR codes to be created dynamically by user input. But I don't want to instantly create a QR code. I want to wait my user to finish writing then after one second i will generate the QR code. So I have a template like below:

<div class="app">
    <qrcode-vue :value="genaratedQrCode"></qrcode-vue>
    <input type="text" v-model="qrCodeInput" />
</div>

And my script:

import QrcodeVue from 'qrcode.vue';

export default {
    data() {
        return {
            genaratedQrCode: '',
            qrCodeInput: '',
            isInputFunctionRunning: false
        }
    },
    watch: {
        async qrCodeInput() {
            if (this.isInputFunctionRunning) {
                return;
            }

            this.isInputFunctionRunning = true;

            await new Promise(r => setTimeout(r, 1000));

            this.genaratedQrCode = this.qrCodeInput;

            this.isInputFunctionRunning = false;
        }
    }
    components: {
        QrcodeVue,
    },
}

Apparently the code is not working. It generated the QR code every one seconds. What I want is waiting till user finished, then updating after 1 seconds.

Boussadjra Brahim
  • 82,684
  • 19
  • 144
  • 164
Mansur
  • 1,622
  • 14
  • 27
  • 1
    How can the browser tell if the user is really finished or is just thinking about what else to type? – Pointy Jul 27 '20 at 15:40
  • It's not about thinking :) It is about finishing "writing". I don't care the reason why he/she stops writing. I just care if he/she stop or not. – Mansur Jul 27 '20 at 15:42
  • What I'm saying is that it is not possible to detect that except via some explicit user action, like focusing on another element. – Pointy Jul 27 '20 at 15:46
  • Hmm. I tried by using an on change method. But async await logic does not work. So is it really impossible or do you have any ideas to achieve it by using onchange? The watch method acts like on change. – Mansur Jul 27 '20 at 15:48

1 Answers1

3

You have to use .lazy modifier :

<input type="text" v-model.lazy="qrCodeInput" />

If you want to wait some delay try this :

import QrcodeVue from 'qrcode.vue';

function debounce (fn, delay) {
  var timeoutID = null
  return function () {
    clearTimeout(timeoutID)
    var args = arguments
    var that = this
    timeoutID = setTimeout(function () {
      fn.apply(that, args)
    }, delay)
  }
}



export default {
    data() {
        return {
            genaratedQrCode: '',
            qrCodeInput: '',
            isInputFunctionRunning: false
        }
    },
    watch: {
        qrCodeInput:debounce(function() {
            if (this.isInputFunctionRunning) {
                return;
            }

            this.isInputFunctionRunning = true;

            this.genaratedQrCode = this.qrCodeInput;

            this.isInputFunctionRunning = false;
        },1000)
    }
    components: {
        QrcodeVue,
    },
}

This is based on this answer;

tony19
  • 125,647
  • 18
  • 229
  • 307
Boussadjra Brahim
  • 82,684
  • 19
  • 144
  • 164