The listener for the 'scan' event in the Instascan QR Code scanner does not update the view of an Angular 5 component

I've integrated Instascan (https://github.com/schmich/instascan) into my Angular 5 application to enable users to scan QR Codes.

Upon successful scanning, I need to perform certain actions and update the view of my component accordingly.

Within my component, the following code is used to identify the cameras available and initiate the scanning process:

cameras: Array<any> = []
selectedCamera: any
scanner: any
content: string

ngOnInit () {
    let vm = this
    Instascan.Camera.getCameras().then(function (cameras) {
      if (cameras.length > 0) {
        vm.cameras.push(...cameras)
      } else {
        console.error('No cameras found.')
      }
    }).catch(function (e) {
      console.error(e)
    })
  }

startScan () {
    let vm = this
    this.scanner = new Instascan.Scanner({
      video: this.videoContainer.nativeElement,
      backgroundScan: false,
      mirror: false
    })
    this.scanner.addListener('scan', function (content) {
      vm.content = content
    })
    this.selectedCamera = this.cameras[0]
    this.scanner.start(this.selectedCamera)
  }

In my template, there is an element that will only appear if 'content' exists. Clicking on it will emit the scanned content to the parent component using an EventEmitter:

<div *ngIf="content" class="btn" (click)="emitContent()">
          PROCEED
        </div>

The issue arises when changes in 'content' within the 'scan' event callback are not reflected in the view, making the 'PROCEED' button invisible. Strangely, these changes become visible after clicking elsewhere on the screen.

Attempts such as using ChangeDetectorRef.detectChanges() method and binding 'this' in the callback have proven ineffective. How can I resolve this problem?

Thank you!

Answer №1

After some trial and error, I was able to tackle this issue by incorporating NgZone in my code:

import { NgZone } from '@angular/core'

constructor (
    private ngZone: NgZone
  ) {}

startScan () {
    this.scanner = new Instascan.Scanner({
      video: this.videoContainer.nativeElement,
      backgroundScan: false,
      mirror: false
    })
    this.scanner.addListener('scan', function (content) {
      this.ngZone.run(() => {
        this.content = content
      })
    }.bind(this))
    this.selectedCamera = this.cameras[0]
    this.scanner.start(this.selectedCamera)
  }

I'm not entirely certain if this is the optimal solution, and frankly, I am unsure about the implications of using NgZone on the performance/state of the application.

If anyone has a more efficient approach, I would greatly appreciate any insights!

Thank you!

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

Setting up a Firebase app across multiple files using Node.js

Trying to organize my methods properly, I want to Initialize Firebase App in multiple files. However, I'm unsure of the best approach. Here is the structure of the file system: /functions |-keys |-methods | |-email.js | |-logger.js |-node_mod ...

Issue with Vue 3: Composition API does not support Array of refs

Check out the code snippet below. <template> <div v-for="item in arr" :key="item">{{ item }}</div> </template> <script> import { ref } from "vue"; export default { name: "TestArr", ...

What is the best way to refresh the DOM following an Ajax request using jQuery?

Is there a way to dynamically update the DOM with newly added records after making a call? Should I fetch the new database record content in the callback function and then append it using jQuery? Please provide guidance if there is insufficient data to a ...

Incorporating HTML content into a Vue component

I'm running into issues trying to display the content of an HTML file within a Vue component. Essentially, I have a Django backend that generates an HTML file using Bokeh and backtesting.py library. On the frontend side, I'm utilizing Nuxt/Vue, w ...

The deployed MVC code encountered an unexpected token "u" in the JSON at position 0

I have a MVC 5 application that is functioning well in the development environment. However, when I publish and deploy it to the testing server (or any other server), I encounter a JavaScript error when clicking on the login button: Uncaught SyntaxError ...

Ways to clear dropdown selection in Vue based on a specific condition?

I am currently developing a dropdown menu for selecting visit status options, which include "pending," "canceled," "rejected," and "approved." In the case of an approved visit status, I would like the dropdown selection to only display the options for "can ...

Obtain the value of a range using JQuery

I made an attempt to retrieve the value of JQuery's range slider when it changes. Here is how I tried: On the HTML/PHP page: <div class="total"> <label for="">Total</label> <p><span class="monthrc"></span ...

Count in JavaScript that picks up where it left off

I'm working on setting up a countdown timer that runs for 24 hours, showing the days, hours, minutes, and seconds. The challenge I'm facing is how to save the progress of the countdown. Essentially, I want it to resume from where it left off for ...

Adding a Bootstrap carousel to an HTML page may cause the inner items to inexplic

I have been working on creating a User Projects section, and I wanted to display the projects in a carousel format. However, when I tried to import Bootstrap carousels, my items suddenly disappeared. Since I am coding on a tablet and not a computer, I am n ...

Tips for submitting a checkbox value even when it is disabled

I attempted to make the checkbox readonly, but users were still able to check/uncheck the field. Next, I tried disabling the checkbox which successfully prevented user interaction. However, when attempting to submit the form, the disabled checkbox value ...

The mat-spinner is continuously spinning without stopping

I am facing an issue with a component (dialog-component) that references another component (DATA-component). In the dialog-component-ts file, when I set isLoaded = false and then use this.isLoaded.emit(true); in DATA-component, the isLoaded value in dial ...

Failed network request in my ReactJS project under the "Auth/network-request-failed" error code

I'm currently working on a project focused on learning to use react-router-dom and firebase authentication for user sign-in and sign-up. However, I've run into an issue where I keep getting a FirebaseError: "Firebase: Error (auth/network-request- ...

Implementing Jquery tabs into the code causes the vertical auto-scroll to smoothly glide beyond anchor points

I recently implemented a smooth autoscroll feature on my webpage using the CSS-Tricks code found here: http://css-tricks.com/snippets/jquery/smooth-scrolling/ Everything was working perfectly until I added jQuery tabs to display some of the content. Now, ...

How can I adjust the alignment of the text in a select menu in jQuery Mobile?

Exploring the world of jquery for the first time, I am excited about building a mobile web application. Utilizing jquery mobile (1.4.5), I encountered a simple issue - I couldn't figure out how to change the location of the text in the select menu. De ...

ng2-select2 prevent selection of initial value

My Angular project has the following setup: Hello.component.html <select2 ngDefaultControl [data]="list" [options]="{ placeholder: placeholder }" > </select2> Hello.component.ts list = [ { id: 1, text: 'Item 1 one' }, { i ...

Updating field based on dropdown value in CakePHP 3.6.11

I have the following tables: customers[id, name, surname, phone, text, balance, created] service_types[id, title, price, length, is_subscription, created] customer_service_types[id, customer_id, service_type_id, price, created] Within the add.ctp file o ...

Sending a JSON object as a map through AJAX to an MVC controller

I am looking to send a map (dictionary) to the MVC controller along with a string parameter. var reportName= 'ReportName'; var FilterValues = new Map([ [0, "value1"], [1, "value2"], [2, "value3"], ]); var model = { reportName: reportName, ...

A collection of jQuery objects that consist of various DOM elements as their properties

Seeking a more concise and potentially more streamlined approach using jQuery. I have an object called lbl which represents a div. Inside this div, there is a span tag that contains the properties firstName and lastName of the lbl object. Here's how t ...

Inject JSON data into a JavaScript array

I am dealing with a JSON file in the following format: [{"excursionDay":"2"},{"excursionDay":"3"},{"excursionDay":"4"}] My goal is to extract the values of excursionDay and store them in an array in JavaScript like this: dayValues = [2,3,4] Here is m ...

Unique rephrased text: "Varied wrapping styles in both

Feeling frustrated with a seemingly commonplace issue. Despite the thousands of times it has been asked before, I can't seem to find an answer on Google. I wanted to neatly display my text within one of my cards, but so far I've only achieved th ...