dorumrr / npmjs-cordova-honeywell-scanner-simplified

A Ionic/Cordova Honeywell Scanner Simplified Plugin for the built-in barcodes scanner.
https://www.npmjs.com/package/cordova-honeywell-scanner-simplified
MIT License
10 stars 19 forks source link

Documentation about multiple ionic pages using the barcode scanner #9

Open leroy0211 opened 3 years ago

leroy0211 commented 3 years ago

Do you have any examples on how to use the barcode scanner when you are using multiple ionic pages?

My use-cases:

I have 2 (or more) pages where input from the barcode scanner is required. The user can switch between those pages whenever they desire.

I'm not sure how to use the .listen, .claim and .release functions.

The problem I have is when I try to listen on both onInit functions, the data is sent to both pages. But only the current active page requires the user's input. When I try to .release on ionViewWillLeave and .claim + .listen on ionViewWillEnter I get nothing, because the initial .listen has never been triggered.

The onInit hook of an ionic page is also only triggered once during the complete lifecycle of an app. Am I missing something? I really could use some help.

PS: I've used the ionic tabs project. The first and third tab both need scanner input. But only if the page is active at that moment. When I'm on tab1, the scanner input is shown on tab1. When I'm on tab3, the input is shown on tab3. Not both at the same time.

leroy0211 commented 3 years ago

I've created an Ionic HoneywellService which should be doing the multi-page thing, by using an activeId.

import { Injectable } from '@angular/core';
import { Observable, Subject } from 'rxjs';
import { filter } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class HoneywellService {
  window: any = window;

  public currentId: string = null;

  private sub: Subject<any> = new Subject<any>();

  constructor() {
    this.window.plugins.honeywell.listen(data => {
      this.sub.next(data);
    });
  }

  listen(id: string): Observable<any> {
    return this.sub.pipe(
      filter(() => id === this.currentId)
    );
  }

  listenAll(): Observable<any> {
    return this.sub.pipe();
  }
}

On several pages you could use:

export class Tab3Page {

  constructor(
    public ngZone: NgZone,
    private honeywell: HoneywellService
  ){
    const scannerData = this.honeywell.listen('my-page-id');   // could be the selector from your @Component
    scannerData.subscribe((data) => {
      this.ngZone.run(() => {
          this.barcodes.unshift(
            `${data} @ ${new Date().toISOString().replace(/[T,Z]/g, " ").split('.')[0]}`
          );
        });
    });
  }

  # You have to activate the currentId per component
  ionViewWillEnter(): void {
    this.honeywell.currentId = 'my-page-id';
  }

  # And you have to deactivate the currentId per component. So data will not be send while component is not visible
  ionViewWillLeave(): void {
    this.honeywell.currentId = null;
  }
}

When you use listen([id] and enter the page (ionViewWillEnter) the currentId will be set. The HoneywellService knows to only send the data from the scanner to that id.

When using listenAll() all the data from the scanner is passed.