How to call the expression function in different page - javascript

I am working on a cordova app and trying to record voice. I need to call expression function outside the declaration. Below is the plugin which I am using, but getting an error - Media undefined and I am unable to access Media object
cordova.define("cordova-plugin-media.Media", function(require, exports, module)
{
var Media = function(src, successCallback, errorCallback, statusCallback) {
argscheck.checkArgs('sFFF', 'Media', arguments);
this.id = utils.createUUID();
mediaObjects[this.id] = this;
this.src = src;
this.successCallback = successCallback;
this.errorCallback = errorCallback;
this.statusCallback = statusCallback;
this._duration = -1;
this._position = -1;
exec(null, this.errorCallback, "Media", "create", [this.id, this.src]);
};
Media.prototype.play = function(options) {
exec(null, null, "Media", "startPlayingAudio", [this.id, this.src, options]);
};
}
var src = "myrecording.mp3";
// Geeting error - Media undefined and I am unable to access Media object
var mediaRecorder = new Media(src,
// success callback
function () {
clearInterval(_media.intervalTimer);
console.log("recordAudio():Audio Success");
},
// error callback
function (err) {
console.log("recordAudio():Audio Error: " + err.code);
}
);

Related

How to read object written through cordova file plugin?

I read on Cordova's documentation for android platform a code snipped and tried to use it for writing a JS object on a text file. The object gets successfully written but when I read it with FileReader API I can't get output as expected.
function writeFile(fileEntry, dataObj, isAppend) {
// Create a FileWriter object for our FileEntry (log.txt).
fileEntry.createWriter(function (fileWriter) {
fileWriter.onwriteend = function() {
console.log("Successful file read...");
readFile(fileEntry);
};
fileWriter.onerror = function (e) {
console.log("Failed file read: " + e.toString());
};
// If we are appending data to file, go to the end of the file.
if (isAppend) {
try {
fileWriter.seek(fileWriter.length);
}
catch (e) {
console.log("file doesn't exist!");
}
}
fileWriter.write(dataObj);
});
}
function readFile(fileEntry) {
fileEntry.file(function (file) {
var reader = new FileReader();
reader.onloadend = function() {
console.log("Successful file read: " + this.result);
//displayFileData(fileEntry.fullPath + ": " + this.result);
};
reader.onload = function(){
k=reader.readAsText(file);
};
reader.readAsText(file);
},onErrorLoadFs );
}
Format of object I want to read :
function sub(name,absent,present){
this.name=name;
this.absent=absent;
this.present=present;
}
var S = new sub('Physics',1,3);
var k= new sub();
What exactly I want to do :
I am writing an object S on the file which appears like this when opened
{"name":"Physics","absent":1, "present" : 3}
Now after reading the file (which in my case is filetoAppend.txt) I want to assign these values to another object k so that when I run k.name, Physics is shown as output.
console output
k
"{"name":"Physics","absent":1,"present":3}"
k.name
undefined
With the Cordova File Plugin, there are two essential pieces of information to remember:
1.Like all Cordova plugins, you have to wait for the deviceready event before you try anything,
2.Then, Use window.resolveLocalFileSystemURL(<path>, <successHandler>, <errorHandler>)
window.resolveLocalFileSystemURL() returns a FileEntry or DirectoryEntry instance (depending on whether you gave a file or a directory as path as its first parameter), which you can then work with.
WRITING TO A FILE
document.addEventListener('deviceready', onDeviceReady, false);
function onDeviceReady() {
function writeToFile(fileName, data) {
data = JSON.stringify(data, null, '\t');
window.resolveLocalFileSystemURL(cordova.file.dataDirectory, function (directoryEntry) {
directoryEntry.getFile(fileName, { create: true }, function (fileEntry) {
fileEntry.createWriter(function (fileWriter) {
fileWriter.onwriteend = function (e) {
// for real-world usage, you might consider passing a success callback
console.log('Write of file "' + fileName + '"" completed.');
};
fileWriter.onerror = function (e) {
// you could hook this up with our global error handler, or pass in an error callback
console.log('Write failed: ' + e.toString());
};
var blob = new Blob([data], { type: 'text/plain' });
fileWriter.write(blob);
}, errorHandler.bind(null, fileName));
}, errorHandler.bind(null, fileName));
}, errorHandler.bind(null, fileName));
}
writeToFile('example.json', { foo: 'bar' });
}
WRITING FROM FILE
document.addEventListener('deviceready', onDeviceReady, false);
function onDeviceReady() {
function readFromFile(fileName, cb) {
var pathToFile = cordova.file.dataDirectory + fileName;
window.resolveLocalFileSystemURL(pathToFile, function (fileEntry) {
fileEntry.file(function (file) {
var reader = new FileReader();
reader.onloadend = function (e) {
cb(JSON.parse(this.result));
};
reader.readAsText(file);
}, errorHandler.bind(null, fileName));
}, errorHandler.bind(null, fileName));
}
var fileData;
readFromFile('data.json', function (data) {
fileData = data;
});
}
cb is the callback function that you need to pass when calling this function
For full reference use:https://www.neontribe.co.uk/cordova-file-plugin-examples/
Updated based on your updated Question
In reader.onloadend you can get the result of the file and assign to your output object k or can call callback function incase.
reader.onloadend = function (e) {
//cb(JSON.parse(this.result));
var k=JSON.parse(this.result);
console.log(k.name + ", " + k.absent+ ", " + k.present);
};
var k = JSON.parse('{"name":"Physics","absent":1, "present" : 3}');
console.log(k.name + ", " + k.absent + ", " + k.present);

Error "The object store currently does not support blob values" when trying to store file in indexedDB

I'm trying to make a storage in javascript using IndexedDB to store blobs.
Here is my code
var Storage = (function () {
function Storage(callback) {
var indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.OIndexedDB || window.msIndexedDB, IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.OIDBTransaction || window.msIDBTransaction, dbVersion = 1.0;
this.URL = window.URL || window.webkitURL;
var request = indexedDB.open('files', dbVersion);
var self = this;
request.onerror = function (e) {
console.log("Error creating/accessing IndexedDB database");
};
request.onsuccess = function (e) {
console.log("Success creating/accessing IndexedDB database");
self.db = request.result;
self.db.onerror = function (event) {
console.log("Error creating/accessing IndexedDB database");
};
// Interim solution for Google Chrome to create an objectStore. Will be deprecated
if (self.db.setVersion) {
if (self.db.version != dbVersion) {
var setVersion = self.db.setVersion(dbVersion);
setVersion.onsuccess = function () {
self.createObjectStore(self.db);
callback();
};
} else {
callback();
}
} else {
callback();
}
};
// For future use. Currently only in latest Firefox versions
request.onupgradeneeded = function (e) {
self.createObjectStore(e.target.result);
};
}
Storage.prototype.createObjectStore = function (db) {
console.log('Creating objectStore');
db.createObjectStore('files');
};
Storage.prototype.putFile = function (fileName, blob) {
console.log('Putting file in IndexedDB');
var transaction = this.db.transaction(['files'], 'readwrite');
var put = transaction.objectStore('files').put(blob, fileName);
};
return Storage;
})();
I'm using it like that :
var storage = new Storage(function () {
var blob = new Blob(['FooBar']);
storage.putFile('test', blob);
});
On Chrome i get :
DataCloneError: Failed to execute 'put' on 'IDBObjectStore': The object store currently does not support blob values.
On Firefox i get :
[Exception... "Data provided to an operation does not meet requirements." code: "0" nsresult: "0x80660005 (DataError)" location: "<unknown>"]
I don't understand what is wrong.
I did find the answer to my question. Well, I did find somthing to resolve the problem : "how to store files permanently in Firefox ?"
I found a FileSystem fallback : https://github.com/ebidel/idb.filesystem.js
It works well.

Public methods in javascript OOP

I want to make a javascript class with methods which I can call within the class as well as outside of the class. I want to make a "public" method, if you will. I want getTextAreaElement and appendTextArea to be such methods.
I've shown a snippet of best code I could come up with so far. I've also tried defining the methods as prototypes as well as within the class (this.func = ...). But that only allowed me to call the method outside (new Socket().appendTextArea("osgjr89");) but NOT within the class itself! The code snippet below shows the exact opposite implementation where I can't call the method outside of the class but can call it within.
Error:
Uncaught TypeError: Object #Socket has no method 'appendTextArea'
socket.js:
function Socket() {
var socket;
var canvas = document.getElementById('c');
var context = canvas.getContext("2d");
if (window.WebSocket) {
socket = new WebSocket("ws://localhost:9012/websocket");
socket.binaryType = 'arraybuffer';
socket.onopen = onopen;
socket.onmessage = onmessage;
socket.onerror = onerror;
socket.onclose = onclose;
} else {
alert("Your browser does not support Web Socket.");
}
function getTextAreaElement() {
return document.getElementById('responseText');
}
function appendTextArea(newData) {
var el = getTextAreaElement();
el.value = el.value + '\n' + newData + " :)";
}
function onopen(event) {
getTextAreaElement().value = "Web Socket opened!";
}
/*[...]*/
}
main.js (loads after socket.js)
$(document).ready(function() {
var s = new Socket();
s.appendTextArea("osgjr89"); // ERROR!
});
UPDATED socket.js:
function Socket() {
[...]
if (window.WebSocket) {
socket = new WebSocket("ws://localhost:9012/websocket");
socket.binaryType = 'arraybuffer';
socket.onopen = this.onopen;
socket.onmessage = this.onmessage;
socket.onerror = this.onerror;
socket.onclose = this.onclose;
} else {
alert("Your browser does not support Web Socket.");
}
this.getTextAreaElement = function() {
return document.getElementById('responseText');
}
this.appendTextArea = function(newData) {
var el = this.getTextAreaElement();
el.value = el.value + '\n' + newData + " :)";
}
this.onopen = function(event) {
this.getTextAreaElement().value = "Web Socket opened!";
}
[...]
}
All public methods must be declared as properties, not variables/functions. So, you have to change stuff like this:
function getTextAreaElement() {
return document.getElementById('responseText');
}
into
this.getTextAreaElement = function() {
return document.getElementById('responseText');
}
If you do this.func = function() {}, you can call the function inside the Constructor (Socket in your case) using this.func() as well as outside using:
var s = new Socket();
s.func();

how to pass callback to onerror method globally?

i have a piece of code for IndexedDB
GetObj = function(storeName, key, callback){
var db = indexedDB.db;
if(db){
var transaction = db.transaction([storeName], transactionType.READ_ONLY);
var obj = undefined;
transaction.oncomplete = function(event) {
if(callback){
callback(obj);
}
};
var objectStore = transaction.objectStore(storeName);
var request = objectStore.get(key);
request.onerror = function (e){
console.log("onError: in", e);
if (callback) {
callback(-1);//error
}
}
request.onsuccess = function(event) {
obj = request.result;
};
}
}
I would like to define the request.onerror function globally so that i can reuse that function for all onerror (instead of copy pasting it all over the place). problem is howto pass callback?
Just define it in a higher scope:
var onerrorHandler = function (e, callback){
console.log("onError: in", e);
if (callback) {
callback(-1);//error
}
};
And then use that for the callback:
... snip
var request = objectStore.get(key);
request.onerror = function (e) {
onerrorHandler(e, callback);
};
... snip
I will rather avoid global error handler.
As you see, the code is not really reduce, but expended to include another wrapper function. In doing so, the error stack trace is not telling which request is causing error.

generic async callback function

this.init = function (onupgradeneeded, onsuccess) {
var openRequest = indexedDB.open(dbName);
openRequest.onupgradeneeded = function (e) {
db = e.target.result;
if (!db.objectStoreNames.contains(objectStoreName)) {
console.log('Creating the ' + objectStoreName + ' objectstore');
db.createObjectStore(objectStoreName, { keyPath: "id", autoIncrement: true });
}
};
openRequest.onsuccess = function (e) {
db = e.target.result;
db.onerror = function (event) {
// Generic error handler for all errors targeted at this database requests
console.log("Database error: " + event.target.errorCode);
};
};
};
Called by:
var idb = new Demo.IndexedDB();
idb.init();
When the init function runs, it will either end up in openRequest.onupgradeneeded or openRequest.onsuccess.
What i would like to know is if its possible to create a generic callback function that gets called in both function. So regardless of which of the two functions that runs i can know when theyre done by using
idb.init(function(){
//onupgradeneeded or onsuccess completed
});
Hope you get the idea, otherwise ill elaborate.
Thanks
Just pass in one callback function and call that one single callback in both cases:
this.init = function (onFinish) {
var openRequest = indexedDB.open(dbName);
openRequest.onupgradeneeded = function (e) {
db = e.target.result;
if (!db.objectStoreNames.contains(objectStoreName)) {
console.log('Creating the ' + objectStoreName + ' objectstore');
db.createObjectStore(objectStoreName, { keyPath: "id", autoIncrement: true });
}
onFinish();
};
openRequest.onsuccess = function (e) {
db = e.target.result;
db.onerror = function (event) {
// Generic error handler for all errors targeted at this database requests
console.log("Database error: " + event.target.errorCode);
};
onFinish();
};
};

Categories

Resources