drew schmaltz
drew schmaltz

Reputation: 1584

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;
        }
    }
})

Upvotes: 9

Views: 10861

Answers (2)

Austin Lovell
Austin Lovell

Reputation: 1049

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 
            })
         });  
      }
   };
});

Upvotes: 3

asgoth
asgoth

Reputation: 35829

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);

Upvotes: 11

Related Questions