BarcodeScanner Example—Continuous Scanning (Legacy)
The HTML template provides the bare minimum for a scanning user interface. There’s an element to display the results of the scans, a bit of static help text, and a button to start scanning.
<!-- barcodeScannerContinuous.html -->
<template>
<div class="slds-text-align_center">
<span class="slds-text-heading_large">BarcodeScanner: Multi-Scan</span>
</div>
<!-- After barcode are scanned, their values are displayed here: -->
<template lwc:if={scannedBarcodes}>
<div class="slds-var-m-vertical_large slds-var-p-vertical_medium
slds-text-align_center slds-border_top slds-border_bottom">
Scanned barcode values are:
<span class="slds-text-heading_small">{scannedBarcodesAsString}</span>
</div>
</template>
<!-- Static help text -->
<div class="slds-text-align_center slds-text-color_weak slds-m-vertical_large">
Click <strong>Start a Scanning Session</strong> to open a
barcode scanner camera view. Position a barcode in the scanner
view to scan it.
<p>Continue scanning items. Click ✖ when there are no
more items to scan.</p>
</div>
<!-- Scan button, always enabled -->
<div class="slds-align_absolute-center slds-m-vertical_large">
<lightning-button
variant="brand"
class="slds-var-m-left_x-small"
icon-name="utility:scan"
label="Start a Scanning Session"
title="Start scanning barcodes, until there are no more barcodes to scan"
onclick={beginScanning}
></lightning-button>
</div>
</template>
This example displays all of the values of successful scans, one after the other. This example is streamlined, omitting some of the comments and processing illustrated in BarcodeScanner Example—Single Scan (Legacy), to focus on the scanning cycle itself.
// barcodeScannerContinuous.js
import { LightningElement, track } from 'lwc';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
import { getBarcodeScanner } from 'lightning/mobileCapabilities';
export default class BarcodeScannerContinuous extends LightningElement {
sessionScanner;
@track scannedBarcodes;
connectedCallback() {
this.sessionScanner = getBarcodeScanner();
}
beginScanning() {
// Reset scannedBarcodes before starting new scanning session
this.scannedBarcodes = [];
// Make sure BarcodeScanner is available before trying to use it
if (this.sessionScanner != null && this.sessionScanner.isAvailable()) {
const scanningOptions = {
barcodeTypes: [this.sessionScanner.barcodeTypes.QR],
instructionText: 'Scan barcodes — Click ✖︎ when done',
successText: 'Successful scan.'
};
this.sessionScanner.beginCapture(scanningOptions)
.then((scannedBarcode) => {
this.processScannedBarcode(scannedBarcode);
this.continueScanning();
})
.catch((error) => {
this.processError(error);
this.sessionScanner.endCapture();
})
}
else {
console.log("BarcodeScanner unavailable. Non-mobile device?");
}
}
async continueScanning() {
// Pretend to do some work; see timing note below.
await new Promise((resolve) => setTimeout(resolve, 1000));
this.sessionScanner.resumeCapture()
.then((scannedBarcode) => {
this.processScannedBarcode(scannedBarcode);
this.continueScanning();
})
.catch((error) => {
this.processError(error);
this.sessionScanner.endCapture();
})
}
processScannedBarcode(barcode) {
// Do something with the barcode scan value:
// - look up a record
// - create or update a record
// - parse data and put values into a form
// - and so on; this is YOUR code
console.log(JSON.stringify(barcode));
this.scannedBarcodes.push(barcode);
}
processError(error) {
// Check to see if user ended scanning
if (error.code == 'userDismissedScanner') {
console.log('User terminated scanning session via Cancel.');
}
else {
console.error(error);
}
}
get scannedBarcodesAsString() {
return this.scannedBarcodes.map(barcodeResult => {
return barcodeResult.value;
}).join('\n\n');
}
}
See Scan Multiple Barcodes (Legacy) for an explanation of how beginScanning() and continueScanning() work together to create the continuous scanning cycle.