The Camera object passed to the CameraCtrl is empty

I am trying to make a simple app to use the phone’s camera. The problem is that the Camera object passed to the CameraCtrl is empty:

angular.module('app.controllers', [])

.controller('CameraCtrl', function($scope, Camera){
    $scope.pictureUrl = "http://lorempixel.com/400/200/";

    $scope.takePicture = function() {
        console.log('taking picture...');
        console.log(JSON.stringify(Camera));
        var options = {
            destinationType: Camera.DestinationType.DATA_URL,
            encodingType: Camera.EncodingType.JPEG
        };

        Camera.getPicture(options)
        .then(
            function(data){
                $scope.pictureUrl = "data:image/jpeg;base64," + data;
            },
            function(error){
            });
    };
})

When I press the “Take Photo” button, I get the following console log:

0 347478 log taking picture…
1 347482 log {}
2 347507 error TypeError: Cannot read property ‘DATA_URL’ of undefined
at Scope.$scope.takePicture (http://192.168.1.105:8100/js/controllers.js:11:52)
at fn (eval at (http://192.168.1.105:8100/lib/ionic/js/ionic.bundle.js:26457:15), :4:224)
at http://192.168.1.105:8100/lib/ionic/js/ionic.bundle.js:62386:9
at Scope.$eval (http://192.168.1.105:8100/lib/ionic/js/ionic.bundle.js:29158:28)
at Scope.$apply (http://192.168.1.105:8100/lib/ionic/js/ionic.bundle.js:29257:23)
at HTMLButtonElement. (http://192.168.1.105:8100/lib/ionic/js/ionic.bundle.js:62385:13)
at HTMLButtonElement.eventHandler (http://192.168.1.105:8100/lib/ionic/js/ionic.bundle.js:16583:21)
at triggerMouseEvent (http://192.168.1.105:8100/lib/ionic/js/ionic.bundle.js:2948:7)
at tapClick (http://192.168.1.105:8100/lib/ionic/js/ionic.bundle.js:2937:3)
at HTMLDocument.tapTouchEnd (http://192.168.1.105:8100/lib/ionic/js/ionic.bundle.js:3064:5)

Here is the content of my services.js file:

angular.module('app.services', [])

.factory('BlankFactory', [function(){

}])

.factory('Camera', ['$q', function($q) {
   return {
            getPicture: function(options) {
            var q = $q.defer();
            navigator.camera.getPicture(function(result) {
                q.resolve(result);
            }, function(err) {
                q.reject(err);
            }, options);
            return q.promise;
        }
   };
}])

.service('BlankService', [function(){

}]);

The beginning of controllers.js file:

angular.module('app.controllers', [])

.controller('CameraCtrl', function($scope, Camera){
    $scope.pictureUrl = "http://lorempixel.com/400/200/";

    $scope.takePicture = function() {
        console.log('taking picture...');
        console.log(JSON.stringify(Camera));
        var options = {
            destinationType: Camera.DestinationType.DATA_URL,
            encodingType: Camera.EncodingType.JPEG
        };

        Camera.getPicture(options)
        .then(
            function(data){
                $scope.pictureUrl = "data:image/jpeg;base64," + data;
            },
            function(error){
            });
    };
})

The app.js file:

angular.module('app', ['ionic', 'app.controllers', 'app.routes', 'app.directives','app.services',])

.run(function($ionicPlatform) {
  $ionicPlatform.ready(function() {
    // Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
    // for form inputs)
    if (window.cordova && window.cordova.plugins && window.cordova.plugins.Keyboard) {
      cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
      cordova.plugins.Keyboard.disableScroll(true);
    }
    if (window.StatusBar) {
      // org.apache.cordova.statusbar required
      StatusBar.styleDefault();
    }
  });
});

And the index.html file:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
    <title></title>

    
    
    <script src="lib/ionic/js/ionic.bundle.js"></script>

    <!-- cordova script (this will be a 404 during development) -->
    <script src="cordova.js"></script>

    <script src="lib/ngCordova/dist/ng-cordova.js"></script>

    <!-- IF using Sass (run gulp sass first), then uncomment below and remove the CSS includes above
    <link href="css/ionic.app.css" rel="stylesheet">
    -->

    
    <link href="lib/ionic/css/ionic.css" rel="stylesheet">
    

    <style type="text/css">
      .platform-ios .manual-ios-statusbar-padding{
        padding-top:20px;
      }
      .manual-remove-top-padding{
        padding-top:0px; 
      }
      .manual-remove-top-padding .scroll{
        padding-top:0px !important;
      }
      ion-list.manual-list-fullwidth div.list, .list.card.manual-card-fullwidth {
        margin-left:-10px;
        margin-right:-10px;
      }
      ion-list.manual-list-fullwidth div.list > .item, .list.card.manual-card-fullwidth > .item {
        border-radius:0px;
        border-left:0px;
        border-right: 0px;
      }
    </style>

    <script src="js/app.js"></script>
    <script src="js/controllers.js"></script>
    <script src="js/routes.js"></script>
    
     
    <script src="js/directives.js"></script>
     
    <script src="js/services.js"></script>
    

    <!-- Only required for Tab projects w/ pages in multiple tabs 
    <script src="lib/ionicuirouter/ionicUIRouter.js"></script>
    -->

  </head>
  <body ng-app="app" animation="slide-left-right-ios7">
  <div>
    <div>
        <ion-nav-bar class="bar-stable">
            <ion-nav-back-button></ion-nav-back-button>
        </ion-nav-bar>
        <ion-nav-view></ion-nav-view>
    </div>
</div>
  </body>
</html>

Camera object is not empty. Camera.DestinationType is empty.
If you change the name of your service, it will work. Service’s name is same as plugin’s object name.

1 Like

Ummm… I changed the name of service from Camera to CordovaCamera and it was fixed! But I just guessed what the correct name should be. How could I name it correctly in the first place? You said service name should be the same as the plugin’s name. Is this plugin’s name CordovaCamera? Where could I find its name?

.factory('CordovaCamera', ['$q', function($q) {

And

.controller('CameraCtrl', function($scope, CordovaCamera){

    $scope.pictureUrl = "http://lorempixel.com/400/200/";

    $scope.takePicture = function() {
        console.log('taking picture...');
        console.log(JSON.stringify(Camera));
        var options = {
            destinationType: Camera.DestinationType.DATA_URL,
            encodingType: Camera.EncodingType.JPEG
        };

        CordovaCamera.getPicture(options)
        .then(
            function(data){
                $scope.pictureUrl = "data:image/jpeg;base64," + data;
            },
            function(error){
            });
    };
})

And now I am noticing that I forgot to change Camera to CordovaCamera in some places and yet it was fixed…

No you misunderstood me. Your service name should not be the same as plugin’s name.
Camera plugin has a Camera object. When you define another object with the same name, object created by the plugin is overwritten and is not available anymore.

1 Like

That was very fool of me. I got it. Thank you :slight_smile: