0

I've refactored my procedural javascript into an object/class and now... I hesitate to say it's broken because I'm not getting any errors but it's (sigh) broken.

In the following code, camera.js: 71 is the last "report" I get from the module. No errors, no barfs, everything proceeds as normal except nothing happens.

I can call either camera.capturePhoto or camera.choosePhoto() and:

  1. I get the camera or the photo library as expected
  2. this.cameraOnSuccess gets called
  3. I get a photo URI back
  4. I get access to the filesystem and at this point either the this.resolveOnSuccess or the anon fuction should handle the error and nothing... nada... zip... zilch. There is no output to the console in either an emulator or within my app.

What did I do wrong (or what lesson am I learning today? ;-)

var camera = new Photo();

function Photo()
{
  var self = this;        // this DOES NOT WORK!
  var element_id = null;
  var dirty_flag = false; // false if clean and no save needed, 1 if save needed
  var callback = null;

  // id is element getting photo
  this.init = function(id, callback) {
    this.element_id = id;
    this.callback = callback;
    this.self = this;   // this works on phonegap / cordova apps        
  }

  this.capturePhoto = function()
  {  
    // the cameraOnFail will never get called with parameters
    // use the method for the self.cameraOnSuccess
    navigator.camera.getPicture(function(entry) {
           self.cameraOnSuccess(entry);
        }, self.cameraOnFail, { quality: 100,
        destinationType: Camera.DestinationType.FILE_URI
    });
  }

  this.cameraOnSuccess = function(imageData) {
    console.log("camera on success");
    this.cleanup();   // this can be called using this as it's a direct call
  }

  this.cameraOnFail = function(message) {
    // trap permission and cancel messages
    console.log("failed because: " +message);
  }

  this.cleanup = function()
  {
      navigator.camera.cleanup(function() {
        console.log("camera.js: 151 = camera cleanup successful");      
      }, function(message) {
        console.log("camera cleanup failed because: " +message);      
      });
  }
}
ppetree
  • 826
  • 3
  • 15
  • 31
  • See the linked dupetarget, it explains the problem. *Normally* you'd get an error in this situation, but it just happens that what you're doing doesn't give you one because when `this.cameraOnSuccess` is called, the only code in `cameraOnSuccess` itself that relies on `this` is the `this.resolveOnSuccess` you're passing into `window.resolveLocalFileSystemURL`. So `cameraOnSuccess` works, but passes `undefined` into `window.resolveLocalFileSystemURL` as the callback -- so the callback isn't called. – T.J. Crowder May 13 '18 at 12:52
  • 1
    Ah crap! I'd forgotten all about that... I even set self=this! Thanks for the answer TJ and glad to see you're still active (you were always a great resource with prototype.js)! – ppetree May 13 '18 at 14:37
  • Oh, wow, now that was a while ago. :-) – T.J. Crowder May 13 '18 at 14:38
  • A day or two... ;-) – ppetree May 13 '18 at 14:38
  • @T.J.Crowder I'm still grappling with 'this'. Inside the function Photo() I set self=this first thing. When I check the value of self in this.init() self is undefined. I thought this was set once camera = New Photo(); was executed? Also, inside of this.init() I could set self=this but I fear that's the wrong this. – ppetree May 13 '18 at 18:18
  • In the code above, `self` within `this.init` will be what `this` was when `Person` was called. Provided you call it with `new` (as you do above), `self` will be the object created by `new`. It definitely won't be `undefined`. – T.J. Crowder May 14 '18 at 06:37
  • when new Photo(); is called, there's a set of variables outside if init() and the first of those is var self = this; That remains undefined unless I call the camera.init() method and explicitly set this.self = this; IOW there is no automatic construction happening. – ppetree May 14 '18 at 16:45
  • *"when new Photo(); is called, there's a set of variables outside if init() and the first of those is var self = this; That remains undefined unless I call the camera.init() method and explicitly set this.self = this"* Not with the code above: https://jsfiddle.net/n6Lcuzcp/ – T.J. Crowder May 14 '18 at 17:00
  • running it on the emulator or in an app console.log("self = " +camera.self); shows as "self = undefined" - after setting this.self = this; in .init() I get "self = [object Object]" but still not getting any further with this. – ppetree May 14 '18 at 17:51
  • Finally! There are three tricks to this in phonegap/cordova. 1st you have to manually set the self and; second, you have to use an anonymous function and reference self.onsuccess() in the anonymous function and third, you have to pass the expected parameters. – ppetree May 14 '18 at 20:04

0 Answers0