Invoke a function within a JavaScript file from a separate file by utilizing a setTimeout method, all while incorporating the power of Angular

I've encountered an issue with my barcode scan detection code. Originally, the code was working fine when it was placed directly in an AngularJS controller. However, I needed to use the same code in another controller as well, so I moved the scan code into a separate JS file that both controllers could access. After including both files in the HTML page, I expected everything to work smoothly. But now, when the scan code detects a barcode scan and tries to call a method on the other controller, I keep getting this error:

0x800a1391 - JavaScript runtime error: 'onBarcodeScan' is undefined

The problematic section in barcodeScan.js looks like this:

setTimeout(function () {
    if (chars.length == 12) {
        var barcode = chars.join("");
        onBarcodeScan(barcode);  // This is where the error occurs
    }
    chars = [];
    pressed = false;
}, 500);

In my AngularJS controller, the function definition for onBarcodeScan is as follows:

var onBarcodeScan = function (barcode) {
    $scope.$apply(function () {
        $scope.state.userEnteredSubId = barcode;
        $scope.onSubmitSubId();
    });
}

I can't seem to figure out what I'm missing. It's worth noting that the order of script inclusion in the index HTML page is correct:

<script src="js/cassetteController.js"></script>
<script src="js/barcodeScan.js"></script>

Answer №1

I stumbled upon a helpful blog post discussing the use of events in an AngularJS factory. Below is the functional code snippet:

Controller:

scannerService.notify();

scannerService.subscribe($scope, function () {
    // Handle notification
    $scope.$apply(function () {
        $scope.state.userEnteredSubId = $rootScope.scan;
        $scope.onSubmitSubId();
    });
});

Factory:

app.factory('scannerService', ['$http', '$rootScope', function ($http, $rootScope) {
    var listenerAdded;

    return {
        subscribe: function (scope, callback) {
            var handler = $rootScope.$on('notifying-service-event', callback);
            scope.$on('$destroy', handler);
        },

        initialize: function () {
            if (listenerAdded) {
                return;
            }
            // Taken from http://www.deadosaurus.com/detect-a-usb-barcode-scanner-with-javascript/:
            listenerAdded = true;
            var pressed = false;
            var chars = [];
            document.addEventListener('keydown', function (event) {
                // Ignore this if the user is hitting enter, or any other non-number.
                if (event.keyCode < 48 || event.keyCode > 57) {
                    return;
                }
                // Only capture numbers, because a subId is all numbers.
                if (event.keyCode >= 48 && event.keyCode <= 57) {
                    // Note: These keycodes are only for numbers along the top of the keyboard; the number pad uses a different range.
                    chars.push(String.fromCharCode(event.keyCode));
                }
                console.log(event.keyCode + ":" + chars.join("|"));
                if (pressed == false) {
                    // Using Angular's $timeout instead of setTimeout to avoid needing $scope.apply().
                    // Reference: http://jimhoskins.com/2012/12/17/angularjs-and-apply.html
                    setTimeout(function () {
                        if (chars.length == 12) {
                            var barcode = chars.join("");
                            $rootScope.scan = barcode;
                            $rootScope.$emit('notifying-service-event');
                        }
                        chars = [];
                        pressed = false;
                    }, 500);
                }
                pressed = true;
            });
        }
    };
}]);

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

Animating numerous elements simultaneously during Vue component rendering

Take a look at this simple case in the following jsfiddle: https://jsfiddle.net/hsak2rdu/ I attempted to swap and animate two elements, but it didn't work as expected. When you click the toggle button in the playground, the second element quickly mo ...

AngularJS - Issue with NgView functionality

Here is the basic setup, with a default noemployee.html partial set as the ng-view Index.html content: <div id="container" ng-controller="EmployeeCtrl"> <!-- Side Menu --> <span id="smenuSpan"> <ul id="thumbList"> <li ng- ...

Creating a virtual roulette wheel with JavaScript

I'm currently working on creating a roulette wheel using JavaScript. While researching, I came across this example: , but I wasn't satisfied with the aesthetics. Considering that my roulette will only have a few options, I was thinking of using ...

Custom directive to change the background image is not functioning as expected

HTML: <div class="has-bg" back-img="{{currentCoverImg}}" style="min-height: 1000px"> ...... </div> I came across a post discussing the correct method of binding data to a directive and using it in my code. The backImg directive is ...

Is Riot.js the best choice for server-side rendering and routing?

Currently, I am using Node along with Riot.js and the Grapnel routing library. I have successfully set up routing on the client side, but I am facing difficulty in making it work on the server side. The functioning of my client router is straightforward. ...

Omit the <span> tag when exporting to XLS format

Currently, I have a functioning jQuery DataTable that utilizes the TableTools plug-in and includes <span> elements in one of the columns for each row. When clicking on the export button, my goal is to exclude or hide the <span> elements from t ...

Tips for updating a nested MongoDB object

Looking to implement a reporting feature for my application When making a PUT request in the front end: .put(`http://localhost:3000/api/posts/report`, { params: { id: mongoId, ...

Angular.js assigns a null value to the model when filtering ng-options

I have two select inputs, one for course categories and another for courses. I need to filter the ng-options based on the selected courses to prevent users from selecting the same course twice. <td> <select ng-show="course._courseId" class= ...

No alteration is made to the value stored in the variable $scope.data

I am facing an issue with the values in $scope.data that are not changing. You can view the problem on this jsfiddle - jsfiddle When you first set Currency: 'UAH' and then change it to Currency: 'RUB', the value of Qty:2 appears to be ...

broadcast a video file from a Node.js server to multiple HTML5 clients at the same time

After researching online, I have been looking for a way to simultaneously stream a video.mp4 to multiple html5 clients. Despite reading various tutorials, I haven't found the ideal solution using nodejs. Do you have any suggestions or alternative met ...

Executing AngularJS controller upon view initialization

I am working on an angularJS single page application that loads views per click. My login and Index are combined in one HTML file. I have managed it using ng-show and ng-if directives. The process is as follows: Index.html and IndexController.js: The log ...

The process of generating collection names dynamically based on user information

My goal is to enhance the structure of my data collection and make it more organized. While I am familiar with accessing and retrieving data, I am unsure about creating the schema. Here is my current schema: var MySchema = new Schema ({ event: { ...

Securing specific pages in Angular front-end: A guide to implementing authentication

Interested in developing a web application using Node.js that allows users to log in (authentication). The app will have 3 non-secure pages (/home, /contact, /about) and one secure page (/admin). I've been consulting the Mean Machine book from scotch. ...

Is it possible to configure Cypress to always open in the current tab instead of opening in a new tab?

One challenge with Cypress is testing on multiple tabs. Our website default to opening in a new tab. Is there a way to make Cypress continue the tests on the same tab? cy.get(element).invoke('attr', 'target', '_self').click() ...

Issue with Durandal dialog repositioning failing to function

I've been attempting to adjust the positioning of a Durandal dialog, but have been unsuccessful so far. The code snippet I'm using is as follows: this.compositionComplete = function (child, parent, context) { dialog.getContext().reposition(c ...

unable to gather information from suppliers

I'm currently building a login page with nextjs and spotify js, but I've run into the following error https://i.sstatic.net/cKiM8.png Here is the code snippet that is causing the issue: import React from 'react' import { getProviders ...

Tips on simulating the Q functions during unit testing in node.js using mocha and rewire!

Struggling with an issue while writing unit tests for node.js. The original code in my file is: var Q=require('q') . . . return Q.all(promises).then(function(data) { _.each(data, function(data) { checking.pu ...

Add a new element to the page with a smooth fade-in animation using jQuery

var content = "<div id='blah'>Hello stuff here</div>" $("#mycontent").append(content).fadeIn(999); Unfortunately, the desired effect is not achieved with this code. I am trying to create a sleek animation when adding new content. ...

Challenge in Decision Making

I am curious why this type of selection is not functioning properly for html select options, while it works seamlessly for other input types like Radios or checkboxes. Any thoughts? $('#resetlist').click(function() { $('input:select[nam ...

Ways to retrieve a specific value in an array of objects

When working with the p5 javascript library, there is a convenient built-in function called {key} that captures the key you press. For instance, using text(${key},200,200) will display the key pressed at position 200, 200 on the canvas. If I were to stor ...