Scan Multiple Barcodes (Legacy)
Sometimes you want to scan many barcodes in a row, without requiring user interaction between scans. For example, when scanning a shelf of inventory, you might not want to stop after each item, or to click a Scan button for every item. In these cases, it can make more sense to click Scan once, and then scan barcodes repeatedly until done with all of the items. Implementing a continuous scanning cycle like this is slightly different from scanning a single item.
- Start a scanning session as usual, with beginCapture().
- When the promise resolves, process the scanned barcode as usual, in the then() block.
- At the end of the then() block, call a new continue scanning function, which uses resumeCapture() to continue the current scanning session.
- Call endCapture() at the end of the catch() block, instead of in the finally() block.
- When the user clicks Cancel to end the scanning session, BarcodeScanner returns a BarcodeScannerError object with a code property value of userDismissedScanner. Handle cancellation and actual errors in the catch() block.
Single Scan vs. Continuous Scan
Single Scan | Continuous Scan |
---|---|
|
|
- The continuous scanning then() block has a call to a new function, continueScanning(). See the Continue a Scanning Session section.
- The call to endCapture() is made in the finally() block for the single scan, but is called in the catch() error handling block for continuous scanning. See the End Capture for Continuous Scanning section.
Continue a Scanning Session
continueScanning() {
this.sessionScanner.resumeCapture()
.then((scannedBarcode) => {
this.processScannedBarcode(scannedBarcode);
this.continueScanning();
})
.catch((error) => {
this.processError(error);
this.sessionScanner.endCapture();
});
}
This code should look familiar; it’s nearly identical to the earlier beginCapture() example for continuous scanning. There‘s only one difference: continueScanning() creates a promise chain by calling sessionScanner.resumeCapture(), while the earlier example called sessionScanner.beginCapture(). It might be obvious, but you only call beginCapture() once, at the beginning of a scanning cycle.
- If the scan is successful, the barcode result is processed, and then the flow of control for the scanning cycle is handed off to continueScanning().
- If the user clicks Cancel, or if there’s an error, the promise chain ends in the catch() error handling block, covered in the End Capture for Continuous Scanning section.
The promise chain in continueScanning() ends the same two ways, with one important difference. While the code is the same, after a successful scan it continues the scanning cycle by calling itself, creating a recursive loop that continues the scanning cycle until the user clicks Cancel, or there’s an error.
Whoops. Didn’t mean to scare you with that word, recursive. Yes, continueScanning() ends by calling itself, which makes it a recursive function. But this recursion is pretty simple—it’s just a loop, an event loop of sorts. The loop handles scan-something events (in the then() block) until a user-clicked-Cancel event comes along (in the catch() block), and then it ends. It might take a minute, but you can wrap your head around it.
- You begin a scanning cycle using beginCapture().
- The promise resolution chain from beginCapture() ends in a call to continueScanning(), your own function.
- continueScanning() continues the existing scanning cycle by calling resumeCapture(), but is otherwise the same as the beginCapture() that started the cycle.
- The promise resolution chain in continueScanning() ends in a call to continueScanning(), creating a scanning cycle loop.
- The loop ends when the user clicks Cancel, BarcodeScanner rejects the promise with a BarcodeScannerError, and you call endCapture() in the error handling catch() block.
The code duplication between the beginCapture() and resumeCapture() promise chains is unfortunate, but unavoidable. Move as much processing code, such as the handling of a scanned barcode, into functions you can call from both chains. In the example here, processScannedBarcode() is a function that both promise chains use to handle a successful scan. See BarcodeScanner Example—Continuous Scanning (Legacy) for the complete sample, which includes that function’s implementation.
End Capture for Continuous Scanning
In a continuous scanning session, the user scans items repeatedly until they’re out of items. Then they click the Cancel button to end the session. In code, BarcodeScanner handles cancellation by rejecting the promise, and returning a BarcodeScannerError to signal that the user canceled scanning. See BarcodeScanner Example—Continuous Scanning (Legacy) for how to distinguish between the user clicking Cancel and an actual error.
Importantly, clicking the Cancel button is the only way to end a continuous scanning session. This is in contrast to a single scan session, which can end with either a successful scan or the Cancel button.
Because continuous scanning always ends with the Cancel button, and thus a BarcodeScannerError, we can call endCapture() in the error handling catch() block.
However, because a single scan might not end in a BarcodeScannerError, the catch() block might never execute. So for a single scan, we put endCapture() in the finally() block, to make sure that, success or failure, it always gets called.