DeviceInformation.name displays Bluetooth version instead of name - javascript

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
}

Related

Web Bluetooth: Can't pair BLE device with Mobile Device with Live Server VS Code extension

I'm a beginner in the Web Development world. I want to pair a BLE device (NRF52840 DK) with my mobile device through a web page. I tested an example for Web Bluetooth and it works fine on my PC as you can see on the following image:
Pairing my PC (Chrome) with a BLE device successfully
I did it through the popular extension Live Server on VS Code. When I tried to access to that page on my mobile (Android) using my IP and port, and pressed the button nothing happened.
Pairing my mobile (Chrome) with a BLE device unsuccessfully
Is there something that I'm not taking into consideration?
Here is the HTML & JS code:
<!DOCTYPE html>
<html>
<head>
<title>BLE WebApp</title>
</head>
<body>
<form>
<button>Connect with BLE device</button>
</form>
<script>
var deviceName = 'Nordic_HRM'
function isWebBluetoothEnabled() {
if (!navigator.bluetooth) {
console.log('Web Bluetooth API is not available in this browser!')
return false
}
return true
}
function getDeviceInfo() {
let chosenHeartRateService = null;
console.log('Requesting Bluetooth Device...')
navigator.bluetooth.requestDevice({ filters: [{ services: ['heart_rate'] }] })
.then(device => device.gatt.connect())
.then(server => {
console.log("Getting HR Serviceā€¦")
return server.getPrimaryService('heart_rate');
})
.then(service => {
chosenHeartRateService = service;
return Promise.all([
service.getCharacteristic('heart_rate_measurement')
.then(handleHeartRateMeasurementCharacteristic),
]);
})
}
function handleHeartRateMeasurementCharacteristic(characteristic) {
return characteristic.startNotifications()
.then(char => {
characteristic.addEventListener('characteristicvaluechanged',
onHeartRateChanged);
});
}
function onHeartRateChanged(event) {
const characteristic = event.target;
console.log(parseHeartRate(characteristic.value));
}
function parseHeartRate(data) {
const flags = data.getUint8(0);
const rate16Bits = flags & 0x1;
const result = {};
let index = 1;
if (rate16Bits) {
result.heartRate = data.getUint16(index, /*littleEndian=*/true);
index += 2;
} else {
result.heartRate = data.getUint8(index);
index += 1;
}
const contactDetected = flags & 0x2;
const contactSensorPresent = flags & 0x4;
if (contactSensorPresent) {
result.contactDetected = !!contactDetected;
}
const energyPresent = flags & 0x8;
if (energyPresent) {
result.energyExpended = data.getUint16(index, /*littleEndian=*/true);
index += 2;
}
const rrIntervalPresent = flags & 0x10;
if (rrIntervalPresent) {
const rrIntervals = [];
for (; index + 1 < data.byteLength; index += 2) {
rrIntervals.push(data.getUint16(index, /*littleEndian=*/true));
}
result.rrIntervals = rrIntervals;
}
return result;
}
document.querySelector('form').addEventListener('submit', function(event) {
event.stopPropagation()
event.preventDefault()
if (isWebBluetoothEnabled()) {
getDeviceInfo()
}
})
</script>
</body>
</html>
I don't think it's possible in the way you describe it.
Web Bluetooth only works on pages which has HTTPS enabled. It works on localhost too for testing purposes. Since you access the web application via an IP-address which doesn't have HTTPS enabled, Web Bluetooth is not available.
https://web.dev/bluetooth/#https-only
You can test this by adding a text to the page with a boolean or other text which will show if web bluetooth is available.
function isWebBluetoothEnabled() {
if (!navigator.bluetooth) {
console.log('Web Bluetooth API is not available in this browser!')
document.getElementById('bluetoothState').innerText = 'Not available'
return false
}
document.getElementById('bluetoothState').innerText = 'Available'
return true
}
use mkcert to create a certificate
usage:
mkcert 127.0.0.1 localhost 0.0.0.0 192.168.0.X
use the files generated to add it to settings.json file in .vscode directory (create if doesn't exist)
{
"liveServer.settings.https": {
"enable": true,
"cert": "/full/path/to/file/192.168.0.108+3.pem",
"key": "/full/path/to/file/192.168.0.108+3-key.pem",
"passphrase": ""
}
}
this will create a warning once due to the nature of self signed certificates, but it'll make sure almost all features of https work.
The issue I faced using this method is that it is considered not secure enough to install a PWA on a local device by chrome.

Communication problem between background script and content script

I am trying to build an addon working on both firefox and chrome in order to get started with extensions (it's not an extension to be published). My aim is basically to recover the mouse movements and a screenshot of the tab and send them through a REST API.
Everything was working fine as of yesterday, but as I am testing today, I am getting an error stating that the content script isn't able to communicate with my background script.
I have checked if a new version of firefox was released overnight and it doesn't seem to be the case to my knowledge. I then have extensively checked the google runtime APIs, and my code seems to be constructed accordingly to the documentation.
What's more intriguing is that everything was working fine even with multiple trials.
If I try to print the content of the sent message, it doesn't print anything.
When I load a temporary addon on firefox, I get a temporary ID, and the error I get is the following :
Error: Could not establish connection. Receiving end does not exist.
background.js:1:745 Unchecked lastError value: Error: Could not
establish connection. Receiving end does not exist. background.js:1
sendRequestToSpecificTab
moz-extension://94826cb7-3494-4f28-abda-e0dbb477ca37/js/background.js:1
I noticed that the ID specified in the error is different than the ID that is provided when I load the addon.
Here is my code :
keylog.js
//capturing the mouse movements
window.addEventListener("mousemove", logMouseMove, false);
window.addEventListener("mousedown", logMouseDown, false);
function logMouseMove(e) {
let currentdate = Date.now();
chrome.runtime.sendMessage({action: "mouselog",data : currentdate+': ('+e.pageX+','+e.pageY+')'});
}
function logMouseDown(e) {
let currentdate = Date.now();
chrome.runtime.sendMessage({action: "mouselog",data :currentdate+': ['+e.pageX+','+e.pageY+']'});
}
And background.js :
"use strict";
let concatenated = "";
let mouse_coord={};
let mouse_json = {};
var id = "";
chrome.runtime.onMessage.addListener(msg => {
var ID = function () {
return '_' + Math.random().toString(36).substr(2, 9);
};
if(msg.action == "mouselog") {
let splitted = msg.data.split(':');
mouse_coord[splitted[0]] = splitted[1];
console.log(msg.data);
if(splitted[1].charAt(0) === '[') {
id = ID();
mouse_json[id] = mouse_coord;
mouse_coord = {};
concatenated += JSON.stringify(mouse_json, null, 4);
let donnes= {};
donnes['id'] = id;
donnes['data'] = mouse_json;
chrome.tabs.query({active: true, currentWindow:true}, (tab) => {
donnes['tab'] = tab;
sendData('http://localhost:33333/mouselog', JSON.stringify(donnes));
});
mouse_json = {};
chrome.tabs.captureVisibleTab(
null,
{},
function(dataUrl)
{
let data = {};
data['id'] = id;
data["data"] = dataUrl;
sendData('http://localhost:33333/saveimg', JSON.stringify(data));
console.log('Sent screenshot');
}
);
try {
chrome.tabs.executeScript(null, {
file: 'injection_script.js'
}, function() {
if (chrome.runtime.lastError) {
message.innerText = 'There was an error injecting script : \n' + chrome.runtime.lastError.message;
}
});
} catch(err) {
console.error(err);
}
}
}
});
I am also declaring on my manifest all the necessary permissions :
"all_urls", "activeTab", "storage", "tabs", "webRequest"
Is there anything I am doing wrong ? I haven't changed a single line to the code that was working last time I tested, so I am doubting the issue may not be from my code, but from the browser ?

ReactJS, Redux and DexieJS (IndexedDB) - Error in incognito mode and Chrome v69

I'm currently learning ReactJS and I decided to create a simple application.
The stack is:
React
Redux
React-router
DexieJS (IndexedDB)
The application is working. The problem is that when I try to test it on Firefox or incognito mode (in Chrome), I get this error:
TypeError: Cannot read property 'apply' of undefined
Anyone knows why I get this error and how I could handle that? I found that IndexedDB is not available in Firefox and incognito mode, so I tried to make a simple check:
if(!window.indexedDB) {
alert('Indexed DB is not supported by your browser. If you are running in incognito mode, please use the normal mode.')
}
But this is not working, I get the error again.
Here is the Github repo if you want to see the whole code:
https://github.com/Webd01/BM
Thanks for your help!
IndexedDB works fine in Chrome incognito mode, so if you have a problem there, it might be caused my something else.
But you are right that IndexedDB is not good in Firefox private browsing mode, although you're wrong about specifically how. window.indexedDB is not null in Firefox private browsing mode, but it does give you an error on upgradeneeded. I use something like this to detect it (this has some other browser compatibility checks too):
var checkIDB = function () {
if (typeof window.indexedDB === "undefined") {
console.log("IndexedDB not supported at all!");
return;
}
try {
keyRange.only([1]);
} catch (e) {
console.log("Buggy Microsoft IndexedDB implementation");
return;
}
var openRequest = window.indexedDB.open('firefox-private-test', 1);
openRequest.onerror = function (evt) {
console.error(evt.target.error);
if (evt.target.error.message.includes("aborted")) {
console.log("Some other error, maybe quota related:");
console.log(evt.target.error);
} else {
console.log("Firefox private mode, probably:");
console.log(evt.target.error);
}
}
openRequest.onupgradeneeded = function (evt) {
var db = evt.target.result;
var one = db.createObjectStore('one', {
autoIncrement: true,
keyPath: 'key'
});
one.createIndex('one', 'one');
one.add({one: 1});
var two = db.createObjectStore('two', {
autoIncrement: true,
keyPath: 'key'
});
two.createIndex ('two', 'two');
two.add({two: 2});
};
openRequest.onsuccess = function (evt) {
var db = evt.target.result;
var transaction;
try {
transaction = db.transaction(['one', 'two'], 'readwrite');
} catch (e) {
console.log("Some browser failed here, maybe an old version of Safari, I forget");
console.log(e.target.error);
return;
}
var count = 0;
transaction.objectStore('one').index('one').openCursor().onsuccess = function (evt) {
cursor = evt.target.result;
if (cursor) {
count += 1;
cursor.continue();
}
};
transaction.oncomplete = function () {
db.close();
if (count === 1) {
console.log("All good!");
} else {
console.log("Buggy Safari 10 IndexedDB implementation")
}
};
};
};

Realtime API Client Reconnection Failure

We've been seeing our realtime documents not reconnecting themselves properly for some time now after disconnecting/connecting WiFi. In particular Safari has a 100% success rate at reproducing this issue for us. Chrome also is susceptible to this same issue although it does a significantly better job than Safari at getting the Realtime API re-connected.
The issue appears to be related to how/if the bind/save XHR requests will be reported as failed to JS when the browser is not connected to the internet. In the case of Safari these requests never fully fail and instead sit and wait forever as no timeout is specified along with the XHR. Once this happens the Realtime API does not try to reconnect itself.
Below are the files that repro this issue 100% in Safari. They will prompt to wait/disable/enable WiFi. Each step may take ~10-20s. Additional information is in the comments. They are also available directly from https://drive.google.com/file/d/0B1es-bMybSeSUmRqX2JJd3dqRFE/view?usp=sharing. The ClientID and ApiKey may need to be modified to make them work properly.
Is anyone else running into similar issues or seen behavior that could be explained by this? Any reasonable workaround ideas apart from detecting this case and clobbering the document?
Edit: And of course 15min after posting this, a potential workaround popped into my head. Not pretty by any stretch of the imagination and may cause other issues, but hijacking the XHR to manually set a timeout to ensure the requests expire appears to fix the issue. [Edit3: Updated to scoped workaround with 70s timeout.]
Workaround
var timeoutURLs =
[
'https://drive.google.com/otservice/save',
'https://drive.google.com/otservice/bind'
];
function shouldSetXHRTimeout(xhr)
{
var shouldSetTimeout = false;
var URLMatch = xhr.url.split('?')[0];
if (timeoutURLs.indexOf(URLMatch) >= 0)
{
shouldSetTimeout = true;
}
return shouldSetTimeout;
}
function wrapXHR()
{
var __send = window.XMLHttpRequest.prototype.send;
window.XMLHttpRequest.prototype.send = function (data)
{
if (!this.timeout && shouldWrapXHRTimeout(this)
{
this.timeout = 70000;
}
__send.call(this, data);
};
};
wrapXHR();
gdrive_connect.html
<!DOCTYPE html>
<html>
<head>
<title>Duchess</title>
<script type="text/javascript" src="//apis.google.com/js/client.js?onload=GoogleApiLoaded" async defer></script>
<script src="gdrive_connect.js" type="application/javascript" ></script>
</head>
<body>
<div id="status">Setting up scenario...</div>
<button id="button" onclick="runScenario()">Run Scenario</button>
</body>
gdrive_connect.js
var clientId = "597847337936.apps.googleusercontent.com";
var REALTIME_MIMETYPE = 'application/vnd.google-apps.drive-sdk';
//
// Problem
// The realtime lib is not reconnecting itself and pushing changes back to the remote server
// after getting disconnected from WiFi in some cases. That is, disconnecting WiFi then reconnecting can
// result in the Realtime API no longer sending or receiving updates for the document that it believes is
// connected.
//
// More Info
// We spent a while tracking down the cause of the issue, and it appears to be with how the bind/save calls
// for the Realtime API are handled if they just 'never return'. In the reconnection failure cases, it
// appears that these network requests never completely 'fail' and instead indefinitely wait without
// notifying the XHR handler.
//
// Hardware
// This was reprod on a MacBook Pro w/ OSX 10.11 on both public WiFi as well as a home WiFi setup.
//
// Software
// This issue repros in both Chrome and Safari. In Safari it happens 100% of the time and will be a
// significantly more consistent repro. Chrome it only happens occasionally and can be fixed by opening and
// closing the laptop. In Chrome this appears to have a different effect on how hung network requests are
// handled than just disabling/enabling WiFi.
//
// Safari
// Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11) AppleWebKit/601.1.56 (KHTML, like Gecko) Version/9.0 Safari/601.1.56
// Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/601.4.4 (KHTML, like Gecko) Version/9.0.3 Safari/601.4.4
// Chrome
// Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.97 Safari/537.36
//
// Repro
// 0) Ensure that the browser/machine are properly connected to the internet and authorized.
// 1) Authorize and load realtime doc.
// 2) Make modification to the document.
// 3) Verify modification was saved remotely.
// 4) Disable WiFi on machine.
// 5) Make modification to the document.
// 6) Verify that the modification did not get saved remotely as machine is offline.
// 7) Enable WiFi on machine.
// 8) Check document's saveDelay to verify that the remote change was not propagated.
// 9) Make additional modification to document.
// 10) Verify that none of the changes have been saved remotely.
//
// The repro requires that you manually disable/enable WiFi and should prompt when to do so. All other info
// is spit out into the console about all of the online/offline related status. When a non-network !!!ERRROR
// is displayed, this means that the repro has been successful. The browser is 100% online, the user is
// authenticated but the realtime document is not flushing its changes to the remote server.
//
// Additional Repro
// While the repro page is enough to 100% consistently cause reconnection issues in Safari, Chrome will fix
// itself in most cases. Disabling/Enabling the WiFi rapidly right after a 'bind' request is made will
// generally also get Chrome stuck not reconnecting to the server.
//
// Console Key
// Delay: The realtime doc's 'saveDelay' field.
// Modified: Time since last modification was made to the doc.
// IsOnline: Whether the browser thinks it is online (navigator.onLine).
// DriveConn: Result of making a separate authenticated request to drive through gapi.
// TokenValid: Whether the gapi.auth authroization token is still currently valid.
// IsOpen: The realtime doc's '!isClosed' field.
//
// The realtime document is accessible through 'window.remoteDoc'.
//
var ReproSteps =
[
'Setting up scenario...', // 0
'Click button to start', // 1
'Connecting...', // 2
'Running... please wait ~10s', // 3
'Disable WiFi', // 4
'Enable WiFi', // 5
'Running... please wait ~10s', // 6
'Done! See error in console' // 7
];
var currentStep = 0;
function setReproStep(index)
{
if (index >= currentStep)
{
var msg = ReproSteps[index];
document.getElementById('status').innerText = msg;
}
}
function GoogleApiLoaded()
{
console.log('Google Remote Client Lib Loaded');
gapi.auth.init();
gapi.client.setApiKey('AIzaSyB9HEdSJ-nhLJG_ssSSqhI2DX74GSiKSao');
gapi.load('auth:client,drive-realtime', function ()
{
console.log('GAPI Loaded Libs');
setReproStep(1);
});
}
function createRealtimeFile(title, description, callback)
{
console.log('Creating Drive Document');
gapi.client.drive.files.insert({
'resource':
{
'mimeType': REALTIME_MIMETYPE,
'title': title,
'description': description
}
}).execute(function (docInfo)
{
callback(docInfo, /*newDoc*/true);
});
}
function openRealtimeFile(title, callback)
{
gapi.client.load('drive', 'v2', function ()
{
gapi.client.drive.files.list(
{
'q': 'title='+"'"+title+"' and 'me' in owners and trashed=false"
}).execute(function (results)
{
if (!results.items || results.items.length === 0)
{
createRealtimeFile(title, /*DocDescription*/"", callback);
}
else
{
callback(results.items[0], /*newDoc*/false);
}
});
});
}
function runScenario()
{
console.log('Page Loaded');
document.getElementById('button').style.display = 'none';
setReproStep(2);
var GScope =
{
Drive: 'https://www.googleapis.com/auth/drive.file'
};
var handleAuthResult = function (authResult)
{
console.log('Requesting Drive Document');
openRealtimeFile("TESTDOC__", function (docInfo, newDoc)
{
if (docInfo && docInfo.id)
{
gapi.drive.realtime.load(docInfo.id, onDocLoaded, onDocInitialized, onDocLoadError);
}
else
{
console.log('Unable to find realtime doc');
debugger;
}
});
};
gapi.auth.authorize(
{
client_id: clientId,
scope: [ GScope.Drive ],
immediate: false
}, handleAuthResult);
}
function onDocInitialized(model)
{
console.log('Drive Document Initialized');
var docRoot = model.createMap();
model.getRoot().set('docRoot', docRoot);
}
var testMap;
var docDataCounter = 0;
var lastWrite = 0;
var remoteDoc;
function onDocLoaded(doc)
{
setReproStep(3);
remoteDoc = doc;
var docModel = doc.getModel();
var docRoot = docModel.getRoot();
console.log('Drive Document Loaded');
// If the loaded document has already been used to test, delete any previous data.
if (docRoot.has('testMap'))
{
console.log('Previous test detected: ' + docRoot.get('testMap').get('testData'));
docRoot.delete('testMap');
}
docRoot.set('testMap', docModel.createMap());
testMap = docRoot.get('testMap');
console.assert(testMap, 'Test map required');
makeDriveDocChange();
doc.addEventListener(gapi.drive.realtime.EventType.DOCUMENT_SAVE_STATE_CHANGED, onSaveStateChange);
beginRunningTest();
}
var VerificationTime = 5000;
var ModificationTime = 10000;
function beginRunningTest()
{
verifyConnectionState();
setTimeout(setReproStep, ModificationTime * 2, 4);
}
var verificationCount = 0;
function verifyConnectionState()
{
setTimeout(verifyConnectionState, VerificationTime);
var saveDelay = remoteDoc.saveDelay;
var isClosed = remoteDoc.isClosed;
var lastModification = Date.now() - lastWrite;
var browserOnline = navigator.onLine;
var currentCount = ++verificationCount;
if (!browserOnline && saveDelay > ModificationTime)
{
setReproStep(5);
setTimeout(setReproStep, ModificationTime * 5, 6);
}
var isTokenValid = verifyAuthToken();
verifyDriveConnection(function (driveConnected)
{
console.log('--------------------- ' + currentCount + ' ---------------------');
console.log(' Delay: ' + saveDelay);
console.log(' Modified: ' + lastModification);
console.log(' IsOnline: ' + browserOnline);
console.log(' DriveConn: ' + driveConnected);
console.log(' TokenValid: ' + isTokenValid);
console.log(' IsOpen: ' + !isClosed);
if (saveDelay > VerificationTime && driveConnected && !isClosed && browserOnline && isTokenValid)
{
console.error('!!! ERROR: Local document not reconnected to remote server. Scenario done.');
setReproStep(7);
}
});
if (lastModification > ModificationTime && saveDelay === 0)
{
makeDriveDocChange();
}
}
function onSaveStateChange(e)
{
}
function verifyAuthToken()
{
var isValid = false;
var token = gapi.auth.getToken();
if (token)
{
var expireTime = parseInt(token.expires_at) * 1000;
if (Date.now() < expireTime)
{
isValid = true;
}
}
return isValid;
}
function makeDriveDocChange()
{
testMap.set('testData', ++docDataCounter);
lastWrite = Date.now();
}
function verifyDriveConnection(cb)
{
gapi.client.drive.about.get({
}).execute(function (res)
{
cb(res && !res.error);
});
}
function onDocLoadError(e)
{
console.log('Doc Load Error: ', e);
findAndLoadDoc();
}

Retrieving Data From Object Not Working in Ionic

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.

Categories

Resources