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;
}
}
})
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);
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
})
});
}
};
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With