I have an Ionic project where I need the Cordova Camera plugin (which I now installed successfully). But in my project the Camera API is still not available, i.e. I get error thrown:
ReferenceError: Camera is not defined
at Scope.$scope.takePic
How do I active the plugin API(s) to be used in an Ionic project? Documentation about this seems to be rather nonexistant or very well hidden.
Open a terminal in your app's root directory and add the plugin via
cordova plugin add org.apache.cordova.camera
Follow these steps:
cordova.js
You can found the same description in the docs.
<script src="lib/ngCordova/dist/ng-cordova.js"></script>
<script src="cordova.js"></script>
You can find this step in the docs in the section of your specific plugin.
cordova plugin add org.apache.cordova.camera
So when using the $cordovaCamera.getPicture
the library is calling internally navigator.camera.getPicture
which is not available when developing in the desktop browser. Further reading
The ngCordova / Ionic team is currently working on mocks you can use to avoid problems like that.
I'm trying to figure out how to use standard Cordova plugins with Ionic myself, but the ionic team just recently built ngCordova--an angular wrapper for common cordova APIs, which includes the Camera api you want to use. Would suggest using that: see their docs for more info.
You need to inject Camera
into the controller, like so:
.controller('MyCtrl', function($scope, Camera) {
Note that there is not a dollar sign before Camera
. This really should be documented more explicitly.
Also, you will need to add a factory to your services.js:
.factory('Camera', ['$q', function($q) {
return {
getPicture: function(options) {
var q = $q.defer();
navigator.camera.getPicture(function(result) {
// Do any magic you need
q.resolve(result);
}, function(err) {
q.reject(err);
}, options);
return q.promise;
}
}
}])
You can install the plugin by run :
$ cordova plugin add org.apache.cordova.camera
Now that you have the plugin installed, you can use the camera API from your Javascript:
function takePicture() {
navigator.camera.getPicture(function(imageURI) {
// imageURI is the URL of the image that we can use for
// an <img> element or backgroundImage.
}, function(err) {
// Ruh-roh, something bad happened
}, cameraOptions);
}
This will prompt the user to take a photo, and will return the local URL of the image that you can then use inside of an tag or use for a CSS background image.
You can use the code below for a simple wrapper over the Camera plugin that makes it easy to asynchronously grab photos:
module.factory('Camera', ['$q', function($q) {
return {
getPicture: function(options) {
var q = $q.defer();
navigator.camera.getPicture(function(result) {
// Do any magic you need
q.resolve(result);
}, function(err) {
q.reject(err);
}, options);
return q.promise;
} } }]);
This factory can be used in your controllers like this:
.controller('MyCtrl', function($scope, Camera) {
$scope.getPhoto = function() {
Camera.getPicture().then(function(imageURI) {
console.log(imageURI);
}, function(err) {
console.err(err);
});
};
Which will open the Camera when getPhoto() is called (from a button click, for example).
Depending on how you request the data back from the Camera and use it in your Angular markup, you may have to whitelist image URLs so Angular allows file:// URLs (for example, if you are using ng-src for an tag):
module.config(function($compileProvider){
$compileProvider.imgSrcSanitizationWhitelist(/^\s*(https?|ftp|mailto|file|tel):/);
})