Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to integrate Phonegap Camera with AngularJS

I'm trying to figure out the best practice for integrating the phonegap camera with AngularJS. The first method I tried was creating a factory with promises that gets called from ng-click. Another way would be putting the code right inside the ng-click within the controller, but then it isn't reusable. Maybe a directive could be made from this? I'm sure there's a few other ways as well. What would the "angularjs" way be?

Here's an example of the factory method that I tried....

The HTML:

<button ng-click="takepic">Take Picture</button>

The controller:

function picturePageCtrl($scope, Camera) {
    $scope.takepic = function() {
        // I'd like to push this into an array of "pics" here.
        // but it is hard to push() with promises.
        Camera.getPic();
    }
}

The factory:

.factory('Camera', function($q) {
    var deferred = $q.defer();
    return {
        getPic: function() {
            navigator.camera.getPicture(
                function (imageURI) {
                    deferred.resolve(imageURI);
                },
                function (message) {
                    deferred.reject(message);
                },
                {
                    quality: 50, 
                    destinationType: Camera.DestinationType.FILE_URI
                }
            );
            return deferred.promise;
        }
    }
})
like image 990
drew schmaltz Avatar asked Jan 27 '13 14:01

drew schmaltz


2 Answers

Personally I would place the logic in a directive, since it will need to access DOM functions (and directives are better suited for that). If you use require: 'ngModel' in your directive, you can use it to store the output value.

Html:

<button camera ng-model='myPicture'>Take Picture</button>

Directive:

app.directive('camera', function() {
   return {
      restrict: 'A',
      require: 'ngModel',
      link: function(scope, elm, attrs, ctrl) {
         elm.on('click', function() {
            navigator.camera.getPicture(function (imageURI) {
               scope.$apply(function() {
                  ctrl.$setViewValue(imageURI);
               });
            }, function (err) {
               ctrl.$setValidity('error', false);
            }, { quality: 50, destinationType: Camera.DestinationType.FILE_URI }
         });
      }
   };
});

In your controller, you can $watch the model and push it into an array:

$scope.myPictures = [];
$scope.$watch('myPicture', function(value) {
   if(value) {
      myPictures.push(value);
   }
}, true);
like image 87
asgoth Avatar answered Nov 04 '22 13:11

asgoth


I added in a few options and corrected the code for other who come across this post like I did. Thank you for your post asgoth!

app.directive('camera', function() {
   return {
      restrict: 'A',
      require: 'ngModel',
      link: function(scope, elm, attrs, ctrl) {


         elm.on('click', function() {
            navigator.camera.getPicture(function (imageURI) {
               scope.$apply(function() {
                  ctrl.$setViewValue(imageURI);
               });
            }, function (err) {
               ctrl.$setValidity('error', false);
            }, { 
                quality : 50,
                destinationType : Camera.DestinationType.DATA_URL,
                sourceType : Camera.PictureSourceType.PHOTOLIBRARY,
                allowEdit : true,
                encodingType: Camera.EncodingType.JPEG,
                targetWidth: 1000,
                targetHeight: 1000,
                popoverOptions: CameraPopoverOptions,
                saveToPhotoAlbum: false 
            })
         });  
      }
   };
});
like image 42
Austin Lovell Avatar answered Nov 04 '22 14:11

Austin Lovell