Retrieving Data From Object Not Working in Ionic - javascript

I've attached $cordovaSQLite to my ionic app. Here is a basic example of the code.
function retrieve() {
var q = $q.defer();
var query = 'SELECT user_credentials, user_id FROM Users;';
$ionicPlatform.ready(function (){
$cordovaSQLite.execute(db, query).then(function(res) {
if (res.rows.length > 0) {
console.log("found user");
console.log(res);
console.log(JSON.stringify(res));
q.resolve(res.rows[0]);
} else {
console.log("no rows found");
q.resolve(false);
}
}, function (err) {
q.reject(err);
});
});
return q.promise;
}
Here is the code to open up the db.
if(window.cordova) {
// App syntax
db = $cordovaSQLite.openDB( "CoolApp.db" );
} else {
// Ionic serve syntax
db = window.openDatabase("CoolApp.db", "1.0", "Cool App", -1);
}
When I test my app on Chrome, my logs show this
rows: SQLResultSetRowList
0: Object
user_credentials: "asdf"
user_id: 234
length: 1
rowsAffected: 0
However when I view the logs when running on my iOS app or Safari, I receive
{"rows":{"length":1},"rowsAffected":0,"insertId":1}
My question is why am I not receiving the value of rows? Why does this work on the browser but not on iOS?

You can get the results by querying the rows.item method with the corresponding index if multiple results were returned.
var elements = [];
for (var i = 0; i < result.rows.length; i++) {
elements.push(result.rows.item(i));
}
return elements;
Where result is the object returned by $cordovaSQL when its promise is complete.

Did you try to instantiate a webSQL instead of SQLite DB for your browser?
You can always just go back to SQLite for your device, but modern browsers like Chrome and Firefox don't support SQLite.

Related

DeviceInformation.name displays Bluetooth version instead of name

Method Windows.Devices.Enumeration.DeviceInformation.findAllAsync returns Collection of DeviceInformation. This object has property name assigned as the Device Bluetooth Name. But instead, the property contains values such as HM-12, SPP Dev or SerialPort which I assume are names of Bluetooth protocols.
Below is the example. Please note that this code was working properly prior Windows upgrade (which version caused this is unknown)
Working on Windows 10 mobile 10.0.14393.67
Windows 10 desktop outputs correct results.
var rfcomm = Windows.Devices.Bluetooth.Rfcomm;
var sockets = Windows.Networking.Sockets;
var streams = Windows.Storage.Streams;
var deviceInfo = Windows.Devices.Enumeration.DeviceInformation;
var cordova = require('cordova');
module.exports = {
connService: null,
connSocket: null,
connWriter: null,
connReader: null,
connDevice: null,
list: function(successCallback, errorCallback) {
setTimeout(function() {
try {
var selector =
rfcomm.RfcommDeviceService.getDeviceSelector(
rfcomm.RfcommServiceId.serialPort);
var parsedDevices = [];
deviceInfo.findAllAsync(selector, null).then(function(devices) {
if (devices.length > 0) {
for (var i = 0; i < devices.length; i++) {
parsedDevices.push({
id: devices[i].id,
name: devices[i].name
})
successCallback(parsedDevices);
}
} else {
errorCallback("No devices found.");
}
}, function(error) {
errorCallback({
error: "list",
message: error.message
});
});
} catch (ex) {
errorCallback(ex);
}
}, 0);
}
}
Value of selector (Windows 10 mobile):
System.Devices.DevObjectType:=10 AND System.Devices.AepService.ProtocolId:="{E0CBF06C-CD8B-4647-BB8A-263B43F0F974}" AND System.Devices.AepService.ServiceClassId:="{B142FC3E-FA4E-460B-8ABC-072B628B3C70}" AND System.Devices.AepService.Bluetooth.ServiceGuid:="{00001101-0000-1000-8000-00805F9B34FB}" AND System.Devices.AepService.ParentAepIsPaired:=System.StructuredQueryType.Boolean#True
Value of selector (Windows 10 PC) - works OK
System.Devices.InterfaceClassGuid:=\"{B142FC3E-FA4E-460B-8ABC-072B628B3C70}\" AND System.DeviceInterface.Bluetooth.ServiceGuid:=\"{00001101-0000-1000-8000-00805F9B34FB}\" AND System.Devices.InterfaceEnabled:=System.StructuredQueryType.Boolean#True
Problem
Your selector is only looking for devices/services that match a serialPort description, which is why you are getting names like SPP Dev or Serial Port.
Solution
Taken from the Windows 10 sample for BluetoothRFcommChat, to find Bluetooth devices use the following AQS query:
// Any extra properties you need
var requestedProperties = null
// The magic happens here, "e0cbf06c-cd8b-4647-bb8a-263b43f0f974" is
// the GUID for any Bluetooth device.
var selector = "(System.Devices.Aep.ProtocolId:=\"{e0cbf06c-cd8b-4647-bb8a-263b43f0f974}\")"
// Then run findAllAsync with these new filters
deviceInfo.findAllAsync(selector, requestedProperties).then(function(devices) {
// Your code here
}

Querying azure mobile services with javascript

I am working on a mobile application using apache cordova.. I have a javascript file that reads data from an azure mobile service and persists it onto the local SQLITE database..
i have a function that is meant to query the azure mobile service but it gives me an error -"cannot read propert 'take' of undefinedType". The function is as follows
function refreshQuestionsTable() {
alert("questions refreshing");
var query = QuestionsTable.take(100).read().done(function (results) {
alert(results.length); //see how many records were returned
for (var i = 0; i < results.length; i++) {
alert(results[i].question); //display the question returned
commitQuestions(results[i].question_id, results[i].client_ref, results[i].question_set, results[i].question_dept, results[i].question, results[i].question_branch, null);
}
},function (err) {
alert("Error: " + err);
});
}
It looks like your client instantiation piece is wrong.
var client = new MobileServiceClient('feedbackmaster.azure-mobile.net/', 'oLMEOExWGFolBhpyYpTFkqvKuLNlyL91');
You had a ';' at the end of your URL for some reason. You should also do a .where() clause that is universally true. Take should work off of that.

Internet explorer 11 Angularjs + NodeJS + Mongoose issue

I'm developping my website with Angularjs framework in the front end , nodejs backend and mongoose to persist my data into a MongoDB database.
In firefox RS v.24 and chrome all is ok, when i add a user into the database, this new user is displayed automatically into my list grid.
But in IE 11 it doesn't until i close the browser and open it back .
when i add a new profile, i do the following in my Controller:
$scope.AddProfil = function() {
$http.post('/ajouterProfils', $scope.profil)
.success(function(data) {
$scope.profilFlag = data; /*unit tests*/
$scope.lastDocId = data._id;
$scope.ajouterProfilTag($scope.lastDocId);
$scope.profil = {};
$scope.tagStyles.length = 0;
$scope.tagStyles = [];
$scope.colorList = {};
angular.element($('.shown-text-add').text($('.shown-text-add').text()));
angular.element($('.shown-text-add').css('font-family', ''));
angular.element($('.shown-text-add').css('font-size', ''));
angular.element($('.shown-text-add').css('line-height', ''));
angular.element($('.shown-text-add').css('font-weight', ''));
setTimeout( function(){$('#addPanel').show();} );
setTimeout( function(){$('#addPanel').fadeOut();}, 2500);
});
};
in my DAO, i have this :
/**
* Add a profile
*/
exports.createProfile = function(req, res) {
var profile = new Profil(req.body);
profile.save(function(err) {
if (err) {
return res.send('users/signup', {
errors: err.errors,
profile: profile
});
} else {
res.jsonp(profile);
}
});
};
Any ideas ? feedbacks ?
As commented, use directives and data binding rather than DOM manipulation.
Clearly this is your problem as you say the data is there when you reload the browser, so the issue is not with the server side components.

Getting result from querying sqlite db in the add-on script to be submitted to the content script

I am writting a modest firefox add-on and I have some problems getting the results used inside the "flow" of the add-on script.
I have the code taking care of querying a sqlite database as a module but I don't know how to create a callback inside of it so that the pagemod in the add-on script can use it and pass it to the content script.
Basically here is what I have:
main.js :
var pageMod = require("sdk/page-mod");
var self = require("sdk/self");
var myDbScript = require('./myDbScript');
pageMod.PageMod({
include: "*.example.com/*",
contentScriptFile: [self.data.url('jquery-1.10.2.min.js'),
self.data.url('myContentScript.js')],
onAttach: function(worker) {
// Query the database on behalf of the content script
worker.port.on('queryTheDB', function(message) {
// Get the data from the DB (é is some test value here)
// Not working because asynchronous querying of the DB
var resultFromDB = myDbScript.getResult(2);
// Send the result to the content script
worker.port.emit('hereIsYourResult', resultFromDB);
});
}
});
myDBScript.js
// Get required components
var {components} = require("chrome");
components.utils.import("resource://gre/modules/FileUtils.jsm");
components.utils.import("resource://gre/modules/Services.jsm");
// Some code to get the DB
// Create statement to retrieve country based on the IP
var statement = dbConnection.createStatement("SELECT col1, col2 FROM table WHERE col1 = :given_col1");
function getResult(submittedValue) {
// Bind parameters
statement.params.given_col1 = submittedValue;
// Execute
statement.executeAsync({
handleResult: function(aResultSet) {
for (let row = aResultSet.getNextRow();
row;
row = aResultSet.getNextRow()) {
var resultFromDB = row.getResultByName("col2");
}
},
handleError: function(aError) {
print("Error: " + aError.message);
return 'error';
},
handleCompletion: function(aReason) {
if (aReason != components.interfaces.mozIStorageStatementCallback.REASON_FINISHED) {
print("Query canceled or aborted!");
return 'canceledOrAborted';
} else {
// Sending the result to the add-on script so that it can
// pass it to the content script
notifyingTheAddonScript(resultFromDB);
}
}
});
}
// Enable the use of the getResult function
exports.getResult = getResult;
The thing is that I don't see how to have the addon script be aware that the result is ready. Please bear with me, I am a noob at this...
Since I don't have the full source, I cannot test. So you'll have to fix any I made errors yourself ;)
First, lets add a callback.
// #param {function(result, error)} callback
// Called upon query completion.
// if |error| is a string, then the query failed.
// Else |result| will contain an array of values.
function getResult(submittedValue, callback) { // changed
// Bind parameters
statement.params.given_col1 = submittedValue;
var rv = [], err = null; // added
// Execute
statement.executeAsync({
handleResult: function(aResultSet) {
for (let row = aResultSet.getNextRow();
row;
row = aResultSet.getNextRow()) {
rv.push(row.getResultByName("col2")); // changed
}
},
handleError: function(aError) {
print("Error: " + aError.message);
err = aError.message; // changed
},
handleCompletion: function(aReason) {
if (aReason != components.interfaces.mozIStorageStatementCallback.REASON_FINISHED) {
print("Query canceled or aborted!");
err = err || 'canceled or aborted'; // changed
}
callback(err ? null : rv, err); // replaced
}
});
}
Lets use this stuff now in the pagemod
onAttach: function(worker) {
// Query the database on behalf of the content script
worker.port.on('queryTheDB', function(message) {
// Get the data from the DB (é is some test value here)
// Not working because asynchronous querying of the DB
myDbScript.getResult(2, function callback(result, error) {
if (error) {
worker.port.emit("hereIsYourError", error);
return;
}
worker.port.emit("hereIsYourResult", result);
});
});
}
You might want to take some precautions not to fire multiple queries. While it would be OK to do so, it might hurt performance ;)
Since our callback already looks kinda like a promise, it might actually be a good idea to use promises, maybe even with the Sqlite.jsm module and some Task.jsm magic.

SQLITE DB not being created - PhoneGap

I have a Phonegap (2.1.0) application that onDeviceready creates a DB and populates a table with info.
Running this locally (using the Ripple emulator) on Chrome works. Tables are being created and populated as required.
After installing the build .apk on my Android device my Eclipse logcat shows:
sqlite returned: error code = 14, msg = cannot open file at line 27712 of [8609a15dfa], db=/data/data/<project>/databases/webview.db
sqlite returned: error code = 14, msg = os_unix.c: open() at line 27712 - "" errno=2 path=/CachedGeoposition.db, db=/data/data/<project>/databases/webview.db
Which I believe according to this post here - can be ignored.
However - I also noticed this error in logcat:
sqlite returned: error code = 1, msg = no such table: latest_events, db=/data/data/<project>/databases/webview.db
I have also - through adb shell - confirmed that the DB is not created:
here: /data/data/com.application/databases.
or here: /data/data/com.application/app_databases
So - my code:
if (!window.openDatabase) {
doMessage('Databases are not supported on this device. Sorry','error');
return;
}else{
consoleLog('all good for storage');
var db;
var shortName = 'MyDB';
var version = '1.0';
var displayName = 'MyDB';
var maxSize = 102400;
function errorHandler(transaction, error) {consoleLog('Error: ' + error.message + ' code: ' + error.code);}
function nullHandler(){};
db = window.openDatabase(shortName, version, displayName,maxSize);
consoleLog('starting table creation');
db.transaction(function(tx){
tx.executeSql( 'CREATE TABLE IF NOT EXISTS latest_events (id integer PRIMARY KEY AUTOINCREMENT,EventID integer,EventLocation text,EventName text,EventDateFrom varchar,EventTime timestamp,EventPresentedBy varchar,EventVenue varchar,EventScript text,RequireRSVP varchar)',[],nullHandler,errorHandler);
db.transaction(function(tx){
tx.executeSql('SELECT count(id) as RowCount FROM device_info ', [],
function(tx, result) {
if (result != null && result.rows != null) {
for (var i = 0; i < result.rows.length; i++) {
var row = result.rows.item(i);
consoleLog('rowcount: '+row.RowCount);
if(row.RowCount==0){
tx.executeSql('INSERT INTO device_info (device_name, device_platform, device_uuid, device_os_ver, date_last_used) VALUES (?,?,?,?,?)',[device.name, device.platform, device.uuid, device.version, window.bowman_config.siteDate],nullHandler,errorHandler);
//doMessage('device info row added','notice');
}
}
}
},errorHandler);
},errorHandler,successCallBack('2'));
//doMessage('device info row added','notice');
},errorHandler,successCallBack('1'));
}
To add to my woes - on my logcat I do see the console.log output for "all good for storage", and the "starting table creation" messages.
My errorHandler functions are not returning anything and my successCallBack functions are triggered...but no DB created.
Thanks for the help.
When you pass in successCallBack("2") and successCallBack("1") then you are actually invoking them directly so you may be getting false positives on whether or not success has actually been called. You should provide two separate success call backs or just in-line some functions that call console.log("1") for instance.
Today this issue cost me 3 hours. What I tried:
Rewriting the copy database code.
Deleting the app from the emulator / device
Wiping emulator(s)
Cleaning eclipse
Changing file permissions
Validate a working SQLite database file
I solved the problem by copying the code from a shared Dropbox account to another location and refactoring the code in the Android Manifest and java files with another package name.
The application runs beautifully now, i.e. nothing wrong with the code, but somewhere it's muxed up by Dropbox.
I broke the nested functions up into single functions and 'chained' them based on their success or fail. It's actually been a lot simpler than I thought. RTFM it seemed. Thanks for all the help.
simplified:
var db = window.openDatabase("TheApp", "1.0", "The App", 50000000);
db.transaction(queryDB, errorCB, successCB);
// Query the database //
function queryDB(tx) {
//tx.executeSql('SELECT * FROM table", [], querySuccess, errorCB);
}
function querySuccess(tx, results) {
//do more functions here
}
function errorCB(err) {
console.log("Error processing SQL: "+err.code);
}

Categories

Resources