Populate an array of Scanner Sources for Select Options with AngularJS

764 views Asked by At

I am working on a web interface for scanning and uploading documents that uses AngularJS client side, and Dynamsoft's Dynamic Web TWAIN to interface with the scanner.

I'm trying to populate a <select> with an array of the available sources retrieved from Dynamsoft's DWObject but the options don't get populated. I think the problem might be that DWObject is initialised after the page has been loaded but I may be wrong. (I'm new to AngularJS).

Here's my code: HTML

<select ng-options="item.label for item in asyncSources track by item.value" ng-model="source">
    <option value="">Select Option</option>
</select>

JavaScript

function scannerController($scope) {

    // Register OnWebTwainReady event. This event fires as soon as Dynamic Web TWAIN is initialized and ready to be used
    Dynamsoft.WebTwainEnv.RegisterEvent('OnWebTwainReady', $scope.Dynamsoft_OnReady);

    // The DWObject is the object that interfaces with all scanner devices
    var DWObject;
    $scope.source = {
        name: '',
        value: 0
    };
    $scope.asyncSources = [];

    // Load the scanner sources
    $scope.loadSources = function () {
        if (DWObject) {
            var count = DWObject.SourceCount; // Populate how many sources are installed in the system

            for (var i = 0; i < count; i++) {
                arr.push({ label: DWObject.GetSourceNameItems(i), value: i })
            }
            $scope.asyncSources = angular.copy(arr);
        }
    }

// Initialise the Dynamsoft Scanner interface
    $scope.Dynamsoft_OnReady = function () {
        Dynamsoft.WebTwainEnv.Unload();
        Dynamsoft.WebTwainEnv.Load();// load all the resources of Dynamic Web TWAIN

        // Delay the retrieval of the Dynamic Web TWAIN Object until AngularJS had fully loaded the page template.
        setTimeout(function () {
            DWObject = Dynamsoft.WebTwainEnv.GetWebTwain('dwtcontrolContainer');// Get the Dynamic Web TWAIN object that is embeded in the div with id 'dwtcontrolContainer'
            if (DWObject) {
                // Allow users to scan more than 2
                DWObject.IfAllowLocalCache = true;
                DWObject.SelectionImageBorderColor = 0xff0000;
                $scope.loadSources();
                // Try load settings from cookies first
                getSourceFromCookie();
                if ($scope.initialSettingsLoad) $scope.initializeSettings();
            }
        }, 2000);
    }

asyncSources gets populated with options, but the select options are not updated.

$scope.asyncSources
[[object Object],[object Object]]
[prototype]: []
length: 2
[0]: {...}
[1]: {...}

JSON.stringify($scope.asyncSources)
"[{\"label\":\"PaperStream IP fi-7160 #2\",\"value\":0},{\"label\":\"HP HD Webcam [Fixed]\",\"value\":1}]"

Updated: Added requested info

1

There are 1 answers

2
Aviad On BEST ANSWER

When 3rd party code updating scope data, you need to fire Angular digest cycle in order to changes take effect because angular don't know that changes has been made.

Calling $digest or $apply tells angular to update and fire any watches.

$scope.asyncSources = angular.copy(arr);
$scope.$apply();

You can also wrap your changes in angular $timeout function to prevent "Error: $digest already in progress" if you're trying to do it in parallel.

$timeout(function(){
  $scope.asyncSources = angular.copy(arr);
});