Search code examples
javascriptangularjsangular-promise

AngularJS ng-click service and promise


I'm always beginner in AngularJS and have a knowledge problem with... That I wanna do is almost simple- a button in a view that trigger a barcode scan and once the scan is complete, populate view fields with the result of the scan.

In the view :

<button id="ajouter-button3" class=" button button-positive  button-block " ng-click="scanBarCode()">Scanner</button>

And later in the view :

        <label class="item item-input " id="add-ean" name="ean">
            <span class="input-label">EAN</span>
            <input type="text" placeholder="Code EAN" name="add.ean" ng-model="add.ean" value="{{add.ean}}">
        </label>

Place in a controller :

    .controller("ajouterCtrl", ["$scope", "$ionicPopup", "$timeout", "ScanDatas", "ScanService" , "storageAreaService", function ($scope, $ionicPopup, $timeout, ScanDatas, ScanService, storageAreaService) {
    "use strict";
    $scope.storageAreas = storageAreaService.storageAreaList();
    $scope.add = {}; // Initalise l'objet


    $scope.scanBarCode = function(){
        ScanService.getBarcodeData().then(function(datas){
            console.log("Retour de la méthode d'acquisition");
            $scope.add.ean = datas.text;
        })
    };

}])

And in the services.js, want to defer to get a promise after the scan is complete, but. I don't understand how defer / promise / function are working together, I tried this :

.factory("ScanService", ["$q", "ScanDatas","$cordovaBarcodeScanner", function ($q, ScanDatas, $cordovaBarcodeScanner) {
var scan = {};

var scanBarCode = function(){
    var readDatas = {};

    $cordovaBarcodeScanner.scan().then(function(datas){
        readDatas.text = datas.text;
        readDatas.format = datas.format;
        readDatas.cancelled = datas.cancelled;
        readDatas.processed = true;
    },function(error){
        readDatas.error = true;
    });

    return readDatas;
}

var getBarcodeData = function(){
    var deferred = $q.defer();

    deferred.resolve(scanBarCode());

    return deferred.promise;
};

return {
    getBarcodeData: getBarcodeData
}
}])

When I run the app... the log is fired immediately in $scope.scanBarCode while I expected that the console.log only fires after deferred.resolve promise. I Don't understand why this happens.


Solution

  • Use this as your service:

    .factory("ScanService", ["$q", "ScanDatas","$cordovaBarcodeScanner", function ($q, ScanDatas, $cordovaBarcodeScanner) {
      var scan = {
        scanBarCode : function(){
          var deferred = $q.defer();
          var readDatas = {};
          $cordovaBarcodeScanner.scan().then(function(datas){
              readDatas.text = datas.text;
              readDatas.format = datas.format;
              readDatas.cancelled = datas.cancelled;
              readDatas.processed = true;
              deferred.resolve(readDatas);
          },function(error){
              readDatas.error = true;
          });
    
          return deferred.promise;
        }
      };
    
      return scan;
    }]);
    

    and call it from controller like this:

    $scope.scanBarCode = function(){
        ScanService.scanBarCode().then(function(datas){
            console.log("Retour de la méthode d'acquisition");
            $scope.add.ean = datas.text;
        })
    };
    

    Thanks!