Search code examples
javascriptvue.jsvuejs3qr-code

QR Code Generator Not Working as Expected


UPDATE: THe original code is now updated to reflect the advice given.

I am trying to create a QR Code generator that changes every minute. I have created the following code, but am receiving some errors, and just need some help with that final push to get this done.

<script>
import { useQRCode } from '@vueuse/integrations/useQRCode'
import { ref } from 'vue'

export default {
  name: 'QRCode Generator',
  data() {
    return {
      custID: ref('[email protected]'),
      getNow: ref(Date.now()),
      text: `${this.custID}?${this.getNow}`
    }
  },
  created() {
    setInterval(this.setQR, 3000)
  },
  methods: {
    getQR() {
      useQRCode(this.text)
    },
    setQR() {
      this.getNow = ref(Date.now())
    }
  }
}
</script>

<template>
  <input id="text" v-model="text" type="text" />
  <img :src="getQR" alt="QR Code" />
</template>

<style scoped></style>

Now I get undefined?undefined for my QRCode string, and the QR Code still doesn't display, probably because I am calling it wrong, and some of the data is undefined.

The way it is supposed to work is that custID is generated from customer data, so that will be dynamic (more than likely an email address), however the getNow is just a timestamp I am using to modify the data being fed to the BarCode Generator, to change it on a minute by minute basis. However the current interval is set to 3 seconds so I can see it working without the wait...

The two custID and getNow value are combined in the text variable and passed to the QRCode generator to change what is displayed, I separate them with a ?.

I've tried a few suggestions from StackOverflow, Google and VueSchool, but no luck.

I have been looking at this for quite a while now, and just need some help tweaking the last piece into place.


Solution

  • I reworked your structure a bit, moving to the composition API and introducing a computed value for your text. I also added a cleanup of the setInterval when the component is unmounted.

    There were a couple of issues with what is much easier to solve with refs, so I upgraded those. The primary issue was that useQRCode() should be called once, and passed a ref or computed that gets updated when you want the image to change.

    <script setup>
    
    import {useQRCode} from "@vueuse/integrations/useQRCode"
    import {tryOnUnmounted} from "@vueuse/core"
    import {computed, ref} from "vue"
    
    const custID = ref('[email protected]')
    const getNow = ref(Date.now())
    
    const text = computed(() => {
      return `${custID.value}?${getNow.value}`
    })
    
    const qrCode = useQRCode(text)
    
    function setNow() {
      getNow.value = Date.now()
    }
    
    let intervalId = setInterval(setNow, 10000)
    
    tryOnUnmounted(() => {
      if (intervalId) {
        clearInterval(intervalId)
        intervalId = null
      }
    })
    
    </script>
    
    <template>
      <input id="text" v-model="text" type="text" />
      <img :src="qrCode" alt="QR Code" />
    </template>