0

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

red_dorian
  • 327
  • 1
  • 6
  • 18
  • It is not clear when you call $scope.loadSources function, can you provide more details? – Aviad Dec 19 '16 at 11:06
  • Can you print console.log(JSON.stringify($scope.asyncSources)) and post? – Akshay Kumar Dec 19 '16 at 11:07
  • @Aviad my apologies, I've added the calling function `$scope.Dynamsoft_OnReady` @AkshayKumar I've added the json output. – red_dorian Dec 19 '16 at 11:59
  • Take a look at this [AngularJS sample of Dynamic Web TWAIN](https://github.com/dynamsoft-dwt/Scan-Documents-with-AngularJS2/blob/master/app/app.component.js) – Rachel Dec 20 '16 at 06:36

1 Answers1

1

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);
});
Aviad
  • 521
  • 2
  • 5
  • That works, thank you Aviad. Though now the select box changes to the first newly added item, index 1. Do you know how I can change it back? I've tried `$scope.source = 0` but that does not affect the select box. – red_dorian Dec 19 '16 at 15:24
  • Use `$scope.source.value = null;`. You can check this fiddle: [https://jsfiddle.net/dmg0jzzh/](https://jsfiddle.net/dmg0jzzh/) – Aviad Dec 19 '16 at 15:39