The BarcodeDetector feature in the Chrome ShapeDetection API is compatible with javascript, but unfortunately does not support typescript integration

I am looking to integrate the BarcodeDetector into my Angular application. After testing the API, I used the following code:

HTML:

<!DOCTYPE html>
<html lang="en>
  <head>
    <script src="./script.js"></script>
  </head>  
  <body>
    <button onclick="scan()">Click here</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 += 'Initiating scan\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';
  }
}

The implementation worked flawlessly. I encountered a NotSupported error on PC but successfully decoded the barcode on my mobile device.

As TypeScript is an extension of JavaScript, I assumed porting the code would be straightforward. However, it proved to be more complex than anticipated. The HTML setup in the Angular app remained similar. Below is the component code:

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 for detector existence yields true, indicating that the detector is available. However, I encounter the following error on both PC and mobile:

TypeError: (void 0) is not a constructor

This issue seems related to the declaration of the decoder, and I'm unsure how to proceed with resolving it.

Answer №1

I encountered the same issue and it took me some time to figure it out. It might not be perfect, but the following solution is working for me.

I want to enable scanning in both scenarios, as this feature is only supported on Mac, Android, and Chrome OS.

I hope this helps! Any feedback is welcome.

<div *ngIf="hasBarcodeDetectorApi" else useWindowsScanning>
  <video id="player" #player></video>

  <div>{{consoleMessage}}</div>
</div>

<ng-template #useWindowsScanning>
  <mso-camera-scan (scanEvent)="onScanNumber($event)" (cameraError)="onCameraError()"></mso-camera-scan>
</ng-template>

The complete component code is provided below, as even reading the barcode requires some effort.

import { AfterViewInit, ChangeDetectionStrategy, Component, ElementRef, EventEmitter, OnDestroy, OnInit, Output, ViewChild } from '@angular/core';

/* 
   Other import statements and component code...
*/

@Component({
  selector: 'mso-barcode-detector',
  templateUrl: './barcode-detector.component.html',
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class BarcodeDetectorComponent implements OnInit, AfterViewInit, OnDestroy {
  
  /* 
     Rest of the component code...
  */
}

Lastly, here's the model required to make everything function smoothly.

// Model definition for barcode detection
// Interface and type definitions...

Answer №2

It seems like your variable is unknowingly replacing the existing window.BarcodeDetector. Additionally, make sure to utilize the result of the feature detection. Feature detection should be approached differently now, as explained in the recently updated guide:

await BarcodeDetector.getSupportedFormats();
/* When executed on a macOS computer, it will log:
  [
    "aztec",
    "code_128",
    "code_39",
    "code_93",
    "data_matrix",
    "ean_13",
    "ean_8",
    "itf",
    "pdf417",
    "qr_code",
    "upc_e"
  ]
*/

This approach allows you to identify the specific feature necessary, such as QR code scanning:

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

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

XMLHttpRequest : Problem with "setRequestHeader" in Firefox

I need to customize request headers for my ajax POST calls, but I'm facing some challenges due to the framework I am using (ZK). I can only set the request headers by overriding certain functions. This is what I have done: var zk_native_function_to_i ...

Error: Ionic 3 is unable to locate the specified pipe

I am unable to locate any issues with this problem. I have already imported it in app.module.ts and included it in the 'declaration' section. In app.module.ts import { NgModule, ErrorHandler } from '@angular/core'; import { BrowserMod ...

When updating data, the cursor in Angular 2 textboxes tends to move to the end of the

I have specific restrictions in the name field that I am attempting to validate using a directive. Within the directive, I am utilizing a regular expression to verify a valid name and then updating the textbox with the valid name using valueAccessor.writeV ...

Ensure that you do not repeat the same action

In my application built on Node.js, I am utilizing Express for API routes and MongoDB as the database. One of the functionalities includes a raffle where users should only be able to enter once. Currently, I am storing participant information in an arra ...

A JavaScript program will only replace strings if a certain local variable has been defined

This is a breakdown of how the script operates: The script first reads the manifest.json file, which includes a list of file names Next, it reads the content of the functions.php file and stores it in a variable named result The script then iterates throu ...

What is the best way to connect to a target property of a dynamically generated form control in Angular 7?

How can I bind to the target property of a dynamically created form control in Angular? Currently, I have code that works for one form control named filingStatus: <drop-down-with-label [formGroup]="controlContainer.control" [options]="dropDow ...

*ngIf - use a property that requires multiple settings

In my Angular 6 project, I have implemented a WIJMO grid in the template that pulls data from a database table. Each row in the grid should display either a delete button or an un-delete button based on the condition specified using *ngIf else: <wj-fle ...

The <mat-radio-button> component does not have a value accessor specified

When working with HTML and Angular, I encountered the following issue: <mat-radio-group> <mat-radio-button [(ngModel)]="searchType"> And (Narrower search) </mat-radio-button> <mat-radio-button [(ngModel)]="searchType"&g ...

Stop inserting repeatedly if there is no new data available

I'm looking for a simple way to implement an if-else statement in my AJAX code to display new data only once it's found, without repeating the same data. Also, I need to figure out how to store the last ID as a variable so that I can use it when ...

What is the best way to identify which JavaScript code is triggering or managing an event?

In the development of an HTML5 application framework designed for businesses to use on their intranet and extranet sites, a SAP JEE application server is utilized. The framework incorporates the grid system known as "Semantic UI" along with various JavaScr ...

Deleting a specific element in React: Step-by-step guide

Having an issue with the handleDelete() method in DisplayList.JSX where it is deleting the first element instead of the selected element. How can this be resolved? Github Display.jsx import {DisplayList} from './DisplayList'; class Display e ...

Executing asynchronous functions within a loop using useEffect

My current scenario is as follows: export default function Component({ navigation }) { const [ item, setItem ] = useState([]); useEffect(() => { AsyncStorage.getItem('someItem') .then(data => JSON.parse(data)) ...

What is the best way to blur the background of the login page when the sign-up form appears?

Seeking assistance with creating a blurry background effect when switching from the login section (#login) to the registration form (#id01). How can this be achieved? Any help would be appreciated. Here is the HTML code: <!DOCTYPE html> <html lan ...

Creating a class in JavaScript based on the name of a background image

I have successfully created div elements using JavaScript, each with a unique background image. Now, I am looking for a way to dynamically add a class name to each div based on the name of its background image in JavaScript or jQuery. // adding divs to ma ...

Implement a function that runs upon Page Load using Javascript

Here is some Javascript code that loads a map with different regions. When you hover or click on a country, additional information about that country is displayed on the right side of the map. I would like to have a random country already displaying infor ...

Flexbox Resizing Notification(?)

Recently, I've been utilizing flexbox in my layout design and it has been a game-changer. However, I am facing an issue that might be linked to my heavy use of AngularJS, particularly the ng-include feature. The specific problem arises when I incorpo ...

Combining JSON Data just like in SQL

Here are some JSON objects: {"COLORS":[[1,red],[2,yellow],[3,orange]]} {"FRUITS":[[1,apple,1],[2,banana,2],[3,orange,3], [4,grenade,1], [5,apple,2]]} I want to convert them to this format: {"FRUITS":[[1,apple,red],[2,banana,yellow],[3,orange,orange], [ ...

Creating collapsible tables with hook functionality in Material-UI

Having trouble resolving this issue, I am seeking assistance with my handleClick() function which is supposed to collapse and expand all table rows simultaneously. The code snippet demonstrating the issue can be found here. Can anyone explain why it is not ...

The Matrixworld of Three.jsMesh is experiencing issues with updating

Good day! I am currently facing a challenge in orienting subpanels on different planes. It seems that the method used to create the mesh for these planes is not updating the matrix and matrixWorld correctly. I need to find a way to ensure that each plane&a ...

When the admin clicks the start button, redirect all users to the designated page

Currently, I am developing a voting application that features both an admin and users. My goal is for the voting campaign to kick off as soon as the admin clicks on the start button. Upon starting the voting process, I aim to redirect all users to a diff ...