Reputation: 85
I'm following this tutorial: https://software.intel.com/en-us/xdk/articles/cordova-core-plugin-camera-short-code-example
It works perfectly fine on my iPhone 5s running iOS 10 with Cordova 6.5.0
However, I don't understand the Logic behind when and what must be placed inside a function that is called when the device is ready.
As you can see, onDeviceReady is called when the device is ready:
document.addEventListener("deviceready",onDeviceReady,false);
// device APIs are available
//
function onDeviceReady() {
pictureSource=navigator.camera.PictureSourceType;
destinationType=navigator.camera.DestinationType;
}
But other API-Calls like taking the actual picture don't require that step (a function that can be called as soon as the button calling it is visible):
// A button will call this function
//
function capturePhoto() {
// Take picture using device camera and retrieve image as base64-encoded string
navigator.camera.getPicture(onPhotoDataSuccess, onFail, { quality: 50,
destinationType: destinationType.DATA_URL });
}
Putting the content of the onDeviceReady function inside the capturePhoto function and waiting several seconds after the page loaded completely breaks the whole thing - why?
Also, why does navigator.camera.DestinationType
differ from the official tutorial which wants you to use Camera.DestinationType
?
Whenever a javascript cordova function is called as soon as the DOM loads it can happen that the native cordova code is not yet ready. But by putting that code inside a onDocumentReady function you can bypass that.
Upvotes: 0
Views: 1333
Reputation: 3574
The deviceready
event is fired after the Cordova APIs are loaded/initialized. If you are using a function from the Cordova API, the best way to guarantee that it has loaded and is thus ready to use, is to only initiate your application logic once the libraries have loaded. I.e. use deviceready
to "initialize" your application.
This is analogous to trying to access an HTMLElement
before the document has loaded (for example, to bind an event handler).
E.g.
class App
{
constructor() {
console.log("Loaded!");
this.bindEvents = this.bindEvents.bind(this);
this.click = this.click.bind(this);
}
bindEvents() {
document.getElementById('button').addEventListener('click', this.click);
}
click() {
navigator.camera.getPicture(...);
}
}
document.addEventListener('deviceready', () => {
// Do all bindings here / start using API.
let app = new App();
app.bindEvents();
}, false);
The reason your "button" works and is starting the camera, is because you happen to be waiting long enough once your app starts up before clicking the button. You can try click the "button" as fast as possible once your app starts. It's possible you'll click it before the device is ready (depends on how long it takes).
Regarding your specific code, all you're doing is creating an "alias" for the Camera API.
Upvotes: 0
Reputation: 316
onDeviceReady event is fired once after full initialization of cordova. When using plugins, all you need to do is to make sure that your call to plugin interface takes place after onDeviceReady() event was catched. You don't need to wait for it every time you need to use plugin. There are other events worth mentioning, here you can read something about cordova application lifecycle: https://cordova.apache.org/docs/en/latest/cordova/events/events.html
Just try to catch different events and print out some console logs to see when different events are fired (good learning technique btw).
When using plugins calls, you need to use namespace where plugin functon is hooked. Sometimes these functions are accessible from different objects, thats why there are some inconsequences in tutorials. To make sure you will call what you want, you can always look to plugin documentation or to plugin www directory, where you can find javascript interface file.
Upvotes: 0