Aprende a crear un lector de códigos QR con Angular 13 🅰

Publicado el 09.07.2022 a las 11:59

Aprende a crear un lector de códigos QR con Angular 13 🅰

Aprende a crear un lector de códigos QR con Angular 13 🅰

La aplicación que vamos a crear no sólo leerá códigos QR, sino que también podrá leer código de barra de toda la vida.

Crearemos el core de la aplicación, será funcional pero no será muy bonita. Ya te encargas tú de darle estilo 😁


¿Cómo será la aplicación que vamos a desarrollar?

Tendrá un desplegable en donde podremos seleccionar que cámara del dispositivo usar y cada 200 ms leeremos la pantalla en busca de algún código, si encontramos alguno válido lo imprimimos en consola y en el HMTL como un párrafo.


Así será 👇


No es la aplicación más bonita del mundo pero funciona.


Al turrón 💻

Puedes descargar o clonar este proyecto desde mi GitHub 👈🚀


Nos vamos a apoyar en una librería que nos va a hacer la vida más fácil, dicha librería es ngx-scanner.

Actualmente tiene más de 20.000 descargar semanales, te dejo aquí el link al repositorio de npm.


La librería es fácil de usar, pero me pegué 2 horas intentando seleccionar la cámara web de mi portátil y por eso me decidí a escribir este artículo.


La versión válida de la librería para Angular 13 es la 3.5.0


Para seleccionar los medios de captura de imagen de tu dispositivo de forma nativa usando la api del navegador 👇

  navigator.mediaDevices.enumerateDevices().then((devices) => {
    for (var i = 0; i < devices.length; i++) {
      var device = devices[i];
      if (device.kind === 'videoinput') {
        console.log(device);
        this.myDevice = devices[1];          
      }
    }
    console.log(this.myDevice);
  });
  

No obstante la librería ya te facilita el método camerasFound


Te dejo todas las propiedades y métodos que puedes usar con la librería


  <zxing-scanner
    [enable]="scannerEnabled"
    [(device)]="desiredDevice"
    [torch]="torch"
    (torchCompatible)="onTorchCompatible($event)"
    (camerasFound)="camerasFoundHandler($event)"
    (camerasNotFound)="camerasNotFoundHandler($event)"
    (scanSuccess)="scanSuccessHandler($event)"
    (scanError)="scanErrorHandler($event)"
    (scanFailure)="scanFailureHandler($event)"
    (scanComplete)="scanCompleteHandler($event)"
></zxing-scanner>
  
ParámetroDefaultDescripción
enabletrueActiva/desactiva el escaneo de la cámara en busca de códigos.
device Será la cámara que se usará para escanear los código.
torch (experimental)Podremos activar/desactivar el flash de la cámara
torchCompatible (experimental)Nos dirá si el flash es compatible con la cámara.
camerasFoundEvento que emite un array de cámaras de tu dispositivo después de que la aplicación haya iniciado.
camerasNotFoundEvento emitido cuando no se encuentran cámaras en tu dispositivo.
scanSuccess Evento que emite la cadena de texto detrás del código leído por la cámara.
scanErrorEvento emitido por un error durante la lectura de la cámara.
scanFailure Evento emitido cuando no se puede leer el código por la cámara.
scanCompleteEvento emitido tras el escaneo de un código, independientemente de si el escaneo es satisfactorio o no.

El código

HTML

            
<select #selectList (change)="selectCamera(selectList.value)">
  <option *ngFor="let camera of cameras" value={{camera.label}}>
    {{ camera.label }}
  </option>
</select>

<zxing-scanner style="width: 500px;"
  [enable]="scannerEnabled"
  [device]="myDevice"
  (camerasFound)="camerasFoundHandler($event)"
  (scanSuccess)="scanSuccessHandler($event)"
></zxing-scanner>
<p *ngFor="let result of results">{{result}}</p>
  
        

El typescript del componente

            
  import { Component, inject } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent {
  title = 'qr-reader';
  public cameras:MediaDeviceInfo[]=[];
  public myDevice!: MediaDeviceInfo;
  public scannerEnabled=false;
  public results:string[]=[];

  constructor() {
  }

  camerasFoundHandler(cameras: MediaDeviceInfo[]){
    this.cameras=cameras;
    this.selectCamera(this.cameras[0].label);
  }

  scanSuccessHandler(event:string){
    console.log(event);
    this.results.unshift(event);
  }

  selectCamera(cameraLabel: string){    
    this.cameras.forEach(camera=>{
      if(camera.label.includes(cameraLabel)){
        this.myDevice=camera;
        console.log(camera.label);
        this.scannerEnabled=true;
      }
    })    
  }
}
  
        

El app.module.ts

            
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { ZXingScannerModule } from '@zxing/ngx-scanner';

import { AppComponent } from './app.component';

@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule, ZXingScannerModule],
  providers: [],
  bootstrap: [AppComponent],
})
export class AppModule {}
  
        

Como ya te he dicho, lo tienes todo en mi GitHub 👈🚀


Hasta luego 🖖

Servicios

Software

IoT

Digitalización

Aplicaciones móviles

Consultoría