html5-qrcode icon indicating copy to clipboard operation
html5-qrcode copied to clipboard

looping in onScanSuccess

Open Cerealex-alex opened this issue 1 year ago • 2 comments

Hello! I'm having trouble with how the scan works and routing: it gets stuck in onScanSuccess looping without any way to stop it that doesn't involve directly clearing it.

I'm using ReactJs.

To Reproduce Steps to reproduce the behavior:

  1. Render a new html5QrcodeScanner with a onSuccess function
  2. Scan a successful code
  3. Result: the onSuccess function loops endlessly

Expected behavior The onSuccess function should set certain variables depending on the decoded text and then stop. It doesn't need to return anything.

Screenshots If applicable, add screenshots to help explain your problem.

Info:

  • "html5-qrcode": "^2.3.8",
  • Browser: Edge

Additional context I've already tried to set a control variable which stores the decoded text, so at the second loop it should check the decoded text, which would be the same, and then not do anything. However, due to the nature of ReactJs Hooks, it doesn't set variables during the loops, even those not using states. I also tried to "return;" without avail.

Also tried just with a console.log to discard a possible self-call.

Another solution to this problem would be a way to store permissions of camera. That way I could render a new Scanner, grant camera permissions, on the onSuccess function clear the scanner and render a new one with those permissions so the user doesn't have to click over and over on the allowing camera button. But I also can't find a way to do this.

Any help is much appreciated. Thank you

Cerealex-alex avatar Nov 12 '23 19:11 Cerealex-alex

@Cerealex-alex Maybe this code can help you:

pauseScan: function (freeze = true) {
    const state = barcodeReader.html5QrcodeScanner.getState();
    if (state === Html5QrcodeScannerState.SCANNING) {
        barcodeReader.html5QrcodeScanner.pause(freeze);
    }
},
resumeScan: function () {
    const state = barcodeReader.html5QrcodeScanner.getState();
    if (state === Html5QrcodeScannerState.PAUSED) {
        barcodeReader.html5QrcodeScanner.resume();
    }
},
onScanSuccess: function (decodedText, result) {
    barcodeReader.pauseScan();
    setTimeout(() => {
        barcodeReader.qrActions.resumeScan();
    }, 1200);
    barcodeReader.qrCodeSuccessHandler(decodedText);
},

muratcakmaksoftware avatar Nov 22 '23 10:11 muratcakmaksoftware

@Cerealex-alex

I struggled with the same thing and ended up doing something similar to what @muratcakmaksoftware mentioned:

    function onScanSuccess(qrCodeMessage) {
        props.setQrCodeResult(qrCodeMessage)
        pauseScanner()
    }

    const startScanner = () => {
        if (html5QrcodeScanner) {
            html5QrcodeScanner.clear()
        }

        const config = createConfig(props);
        const verbose = props.verbose === true;

        html5QrcodeScanner = new Html5QrcodeScanner(
            qrcodeRegionId,
            config,
            verbose
        );

        html5QrcodeScanner.render(
            onScanSuccess,
            props.qrCodeErrorCallback
        );

        props.setIsScanning(true);
    };

    const pauseScanner = () => {
        if (html5QrcodeScanner) {
            html5QrcodeScanner.pause()
        }
    }

    const resumeScanner = () => {
        if (html5QrcodeScanner) {
            html5QrcodeScanner.resume()
        }
    }

urosran avatar Feb 12 '24 23:02 urosran