Load JS files before anything else (jQuery and other JS libraries)

Hello everyone,

After struggling to make the QR Scan native plugin work on a pure browser (not Android or iOS app), apparently even if the the plarform “browser” is mentionned as compatible, it doesn’t mean it will work (see thread here ). I am a rookie, but I see a lot of people struggling with this topic…

So I turned to a pure HTML QR code scanner, and I managed to make it work as standalone on my laptop’s browser (not on mobile, but I assume it’s because I have to set the server with https to allow webRTC). Here is the HTML5 plugin. There is a simple test html page here.

The downsides of using this are: it requires jQuery (and I know most people advice against mixing jQuery and Angular2) and it extends jQuery with other functions (.html5-qrcode() among others).
Basically, in a normal webpage I would just load jQuery, then the 2 other JS scripts, like they do in the example, and it just works.

But how do I do this in my Ionic3 app? If I include the JS files in index.html, they are not always loaded before transpiling, and therefore $ is not recognized and the function .html5-qrcode not found.
If I use the import * as $ from 'jquery' on my page .ts file, it solves the $ issue but not the function not found…

Is there a way to tell ionic to load these external JS functions before trying everything else?

Thank you very much for your help!

I will reply to myself :smiley: because I figured out a solution.

The transpile process was giving errors because the $ and the functions html5_qrcode and html5_qecode_stop were not being read from the JS files that I included in index.html in time. They were eventually, but not a the time the page .ts was being processed.

I bypassed the transpiler error by declaring both in the page .ts file (like you would with prototypes):

declare var $: any;
declare function html5_qrcode(any);
declare function html5_qrcode_stop(any);

Not sure it’s the best solution, but it is one.
Hope this helps someone :slight_smile:

1 Like

Hello Cesar,

I’m starting with ionic and I do not know how to integrate with html5-qrcode. Can you please explain how you did it?

Thank you for your help.

Hello @vanilsonsp

I will give the skeleton, it will be up to you to adapt it to your project.

What I did is this.

In your index.html, include the JS QR code reading libraries. You have several, in my case I chose instascan (because it seemed much more reliable than any other I tested before). So I included, just before cordova.js:

<script type="text/javascript" src="assets/js/instascan3.js"></script>

I assume you created a ionic page for the scanner.

In your page html, add a video element with id=“preview” (use the css to make sure it is visible, with a height and width not equal to 0):

<video id="preview" autoplay playsinline></video>

In your .ts file of the given ionic page, first declare InstaScan (or whatever library you are using) as a prototype. Just after the imports, before the @Component or export class:

declare var Instascan: any;

(This is needed to avoid errors during transpiling, because the js library is loaded in index.html in real life, but when transpiling, it is not found. Doing this you are just declaring “this function exists” even though you do not say what it does right now).

Then just create a function in the export class that is launched when the view is loaded.

ionViewDidLoad() {
    this.startScanner();
}

startScanner() {
    let opts = {
      // Whether to scan continuously for QR codes. If false, use scanner.scan() to manually scan.
      // If true, the scanner emits the "scan" event when a QR code is scanned. Default true.
      continuous: true,

      // The HTML element to use for the camera's video preview. Must be a <video> element.
      // When the camera is active, this element will have the "active" CSS class, otherwise,
      // it will have the "inactive" class. By default, an invisible element will be created to
      // host the video.
      video: document.getElementById('preview'),

      // Whether to horizontally mirror the video preview. This is helpful when trying to
      // scan a QR code with a user-facing camera. Default true.
      mirror: false,

      // Whether to include the scanned image data as part of the scan result. See the "scan" event
      // for image format details. Default false.
      captureImage: false,

      // Only applies to continuous mode. Whether to actively scan when the tab is not active.
      // When false, this reduces CPU usage when the tab is not active. Default true.
      backgroundScan: false,

      // Only applies to continuous mode. The period, in milliseconds, before the same QR code
      // will be recognized in succession. Default 5000 (5 seconds).
      refractoryPeriod: 5000,

      // Only applies to continuous mode. The period, in rendered frames, between scans. A lower scan period
      // increases CPU usage but makes scan response faster. Default 1 (i.e. analyze every frame).
      scanPeriod: 1

    };

    let _this = this;

    _this.scannerObject = new Instascan.Scanner(opts);
    _this.scannerObject.addListener('scan', function (content) {

      //Show the content read from the QR code
      alert(content);
      console.log("QR READ: " + content);
      
      //And you can create your conditions here, to check the value of the scanned content
     
    });

I think this should be enough for you to make it work… I hope it helps anyway.

Good luck!

1 Like

Don’t do this:

document.getElementById('preview'),

You should use the ViewChild decorator to grab the ElementRef instead of using document:

  @ViewChild('video')
  public video: ElementRef;

Also see:

Hello cesarmiguel85,

Thank you very much for the help. I studied a lot and made my code work, but it looks like your code is better than mine :). I will try to improve it. I still do not know the ionic very well but we can exchange ideas. I am studying and developing a loyalty card project.

Greetings,

Vanilson