Chrome ShapeDetetion API BarcodeDetector works with javascript but not with typescript

Viewed 1111

I want to implement the BarcodeDetector in an Angular app. I tested out the API with the following code:

HTML:

<!DOCTYPE html>
<html lang="en">
  <head>
    <script src="./script.js"></script>
  </head>  
  <body>
    <button onclick="scan()">Click me</button>
    <img src="./barcode.gif">
    <pre></pre>
  </body>
</html>

JavaScript:

function scan() {
  const images = document.querySelectorAll('img');
  const pres = document.querySelectorAll('pre'); 
  try {
    pres[0].textContent += 'started\n';
      let barcodeDetector = new BarcodeDetector();
      pres[0].textContent += 'created and detecting\n';
      barcodeDetector.detect(images[0]).then(detectedCodes => {
      for (const barcode of detectedCodes) {      
        pres[0].textContent += barcode.rawValue  + '\n';
      }}).catch((e) => {
    pres[0].textContent += e + '\n';
  });
  } catch (e) {
    pres[0].textContent += e + '\n';
  }
}

and it works perfectly. On the PC I got a NotSupported error and the decoded barcode when I opened the page on my phone.

Since TypeScript is a superset of JavaScript I tought that it should be quite simple to port the code but, apparently it isn't. The HTML in the angular app pretty much the same. The component code is the following:

var BarcodeDetector: any;

@Component({
    templateUrl: './index.component.html'
})
export class IndexComponent {

    @ViewChild('imgRef')
    image: ElementRef;

    hasBarcodeDetector = '';
    errors = '';
    scanData = '';

    constructor() {
        try {
            this.hasBarcodeDetector = 'BarcodeDetector' in window ? 'true' : 'false';
            const barcodeDetector = new BarcodeDetector();
            barcodeDetector.detect(this.image.nativeElement).then(detectedCodes => {
                for (const barcode of detectedCodes) {
                    this.scanData += barcode.rawValue + '\n';
                }
            });
        } catch (e) {
            this.errors = e;
        }
    }
}

The check whether the detector exists works, because I get true, but both on PC and mobile I get the following error:

TypeError: (void 0) is not a constructor

I'm guessing it has something to do with the declaration of the decoder, but I really have no idea on what to do.

1 Answers

I think with your variable you're accidentally overwriting the window.BarcodeDetector. Also note that you're not making use of the result of the feature detection. Feature detection, by the way, should happen differently now, as outlined in the recently updated article:

await BarcodeDetector.getSupportedFormats();
/* On a macOS computer logs
  [
    "aztec",
    "code_128",
    "code_39",
    "code_93",
    "data_matrix",
    "ean_13",
    "ean_8",
    "itf",
    "pdf417",
    "qr_code",
    "upc_e"
  ]
*/

This allows you to detect the specific feature you need, for example, QR code scanning:

if (('BarcodeDetector' in window) &&
    ((await BarcodeDetector.getSupportedFormats()).includes('qr_code'))) {
  console.log('QR code scanning is supported.');
}
Related