capacitor-community / barcode-scanner

A fast and efficient (QR) barcode scanner for Capacitor
MIT License
437 stars 172 forks source link

StopScan() is not enough #193

Closed Travisaurus-Rex closed 1 year ago

Travisaurus-Rex commented 1 year ago

Calling await BarcodeScanner.stopScan() will only deactivate the scanner itself, but what it does NOT do is cancel the call that opened it in the first place. My app will wait for const result = await BarcodeScanner.startScan() and continue to hang until the app is closed entirely.

pettys commented 1 year ago

@Travisaurus-Rex I see this is closed, but without explanation. I'm contemplating a work-around for what you've described above and wondering what others are doing.

pettys commented 1 year ago

I did some further research and found this issue was resolved in later versions: https://github.com/capacitor-community/barcode-scanner/pull/51

thegnuu commented 1 year ago

Yes, as far as I know, this should work in the current version, but I have not tested it properly, to be honest.

I am working on a new version of the plugin anyway which will get rid of the "redundant" implementation of startScan and startScanning so this should resolve itself in an upcoming version if there are still some edge cases where it might fail.

pettys commented 1 year ago

I'm on v1.2.1 of this plugin, which has the dangling promise problem. I'm using Promise.race() to workaround this; here's what it looks like, in case anyone else is like me, in a spot where they can't update the plugin yet.

My code before this workaround:

async myScanFunction() {
    const result = await BarcodeScanner.startScan({});
    if (result.hasContent) {
        return result.content;
    } else {
        return null;
    }
}

My code with this workaround:

async myScanFunction() {
    const cancelBtn = // code to create and position a <button>
    const cancelPromise = new Promise(resolve => {
        cancelBtn.addEventListener('click', () => {
            BarcodeScanner.stopScan();
            resolve({hasContent: false});
        });
    });
    const scanPromise = BarcodeScanner.startScan({});
    const result = await Promise.race([scanPromise, cancelPromise]);
    if (result.hasContent) {
        return result.content;
    } else {
        return null;
    }
}