How to retrieve data from SQLite on Android - android

I am working on a project that uses Ionic 1 and AngularJS. I have successfully stored data in SQLite. On the simulator of the Ionic (using ionic serve --lab) the data is displayed (console.log()) as follows:
SQLResultSetRowList {0: {…}, length: 1}
0: { // data }
length: 1
So I can get the data easily from accessing the object in the result array. However, on real mobile device (I am testing on Android), the data is displayed like this.
The problem is in here. I want to access the rows inside the Closure of that <function scope> that is inside the item: function, which I really don't know how it is generated (and I mean all of these) because the only result I want is as how I got just like in the simulator.
This is how I inserted the data.
$cordovaSQLite.execute(db, "INSERT OR REPLACE INTO token (token) VALUES (?)", [myData]).then(function (res) {
callback();
}, function (error) {
ErrorHandler.handle(error);
});
This is how I query the data.
$cordovaSQLite.execute(db, "SELECT * FROM token").then(function (res) {
console.log(res);
}, function (error) {
ErrorHandler.handle(error);
});
Anyone has an idea to solve this?
Any way is acceptable.

Okay. I have found the solution to solve this problem myself from this.
I need to use it like this.
if (res.rows.length > 0){
if (window.cordova) {
// Mobile Device
console.log(JSON.parse(res.rows.item(0)));
} else {
// Web
console.log(JSON.parse(res.rows[0]));
}
}

Related

Endless loop in dialogflow v2 detectIntent after having split one input query in two queries

Per default, Dialogflow can only match one intent per one one input:
e.g
User asks: "How are you?"
Dialogflow Agent responds: "I am feeling good!"
(Matched intent: intents.howareyou)
But as soon as the user asks two questions in one input, the agent can not match multiple intents. Only one intent is matched with a smaller confidence interval)
e.g
User asks: "How are you? Do we want to go shopping?"
Dialogflow Agent responds: "Yes, lets go shopping!"
(Matched intent: intents.shopping)
There are two options now to enable the agent to answer both questions in one input:
Create an intent and let the agent response exactly for these two questions.
=> This is a very bad solution, as soon as you add more possible questions/intents. Then you would need to create every combination of every question.
Split the one input into several queries and let the agent perform the intent matching again on the splitted query.
=> This is the preferred way
Based on some blogs in the internet (e.g. https://docs.meya.ai/docs/handle-multiple-intents-in) the second option is what I did.
The Default Fallback Intent is set to use the Fulfillment webhook and this a small part of code executed:
function parseMultipleIntents (agent) {
const query = agent.query;
var pattern= /(.+?[!.?]+)/gm;
var match = pattern.exec(query);
while (match !== null) {
console.log(match[0]);
handleQuery(match[0]); //<----
match = pattern.exec(query);
}
}
The handleQuery method is the actual method, where the splitted queries are handled:
function handleQuery(query){
console.log(query);
// The path to identify the agent that owns the created intent.
const sessionPath = sessionClient.sessionPath("PROJECT_ID", "FIXED_SESSION_ID");
const request = {
session: sessionPath,
queryInput: {
text: {
text: query,
languageCode: 'de',
},
},
};
sessionClient
.detectIntent(request)
.then(responses => {
console.log('Detected intent');
const result = responses[0].queryResult;
console.log(` Query: ${result.queryText}`);
console.log(` Response: ${result.fulfillmentText}`);
if (result.intent) {
console.log(` Intent: ${result.intent.displayName}`);
} else {
console.log(` No intent matched.`);
}
})
.catch(err => {
console.error('ERROR:', err);
});
}
The problem:
If I comment everything in the handleQuery method except console.log(query); then the console outpuut in the firebase console looks fine:
originalQuery: und?warum?
11:39:58.240 PM dialogflowFirebaseFulfillment warum?
11:39:58.238 PM dialogflowFirebaseFulfillment und?
But as soon as I uncomment the rest of the handleQuery and the code looks like above, I get the following console messages which is not stopping. The messages go one if I scoll up in the console. It seems like some kind of loop:
-
-
Do I use detectIntent correctly or do you had such experiences? Or can you spot an issue?
I presumed issues with sync/async calls and also added Promises, but the same happened...
Thanks

WIX Store - Get list of products from their API to show on mobile app

I am an Android Developer and 0 knowledge in Wix. Is it possible to get a list of products from Wix Store to display it on Android app. I cannot find any documentation for Android.
This is my test website
https://sakurafukuyoshi031.wixsite.com/juhachipawnshop/shop-1
I just want to know if it is possible to get the data so I can display it on my app from their API maybe by using javascript or the webview javascript injection methods Thanks
There isn't an API for Wix Stores just quite yet, but it's coming soon - https://www.wix.com/code/home/coming-soon
There's a way to expose a collection by creating an API using the wix-http-functions but it appears that it's limited to exposing custom collections - not Wix's native collections (Stores/Collections or Stores/Products). The example on the wix-http-functions is pretty self explanatory. Below a modified version of it:
// In http-functions.js
import {ok, notFound, serverError} from 'wix-http-functions';
import wixData from 'wix-data';
// URL looks like:
// https://www.storename.com/_functions/storeProducts/1
// or
// https://user.wixsite.com/mysite/_functions/storeProducts/1
export function get_storeProducts(request) {
let options = {
"headers": {
"Content-Type": "application/json"
}
};
let pagesize=50;
// query a collection to find matching items
return wixData.query("Stores/Products")
// If you replace the "Stores/Products" with a custom collection name it works
.skip((request.path[0] - 1) * pagesize)
.limit(pagesize)
.find()
.then( (results) => {
// matching items were found
if(results.items.length > 0) {
options.body = {
"items": results.items
};
return ok(options);
}
// no matching items found
options.body = {
"error": `'${request.path[0]}' was not found`
};
return notFound(options);
} )
// something went wrong
.catch( (error) => {
options.body = {
"error": error
};
return serverError(options);
} );
}
Unfortunately this produces an error with the native collections such as "Products"
{"error":{"name":"Error","errorGroup":"User","code":"WD_SCHEMA_DOES_NOT_EXIST"}}
(I could not find any documentation for the error - so this is where I got stuck)
If you then create a custom collection in Wix Code under "Database", export the products from "Stores/Products" into a CSV - and then import the CSV into the custom collection (and finally publish/sync the custom collection) you can workaround the apparent limitation of exposing the native product catalog via a custom API. It's not ideal - but could work if your catalog is not changing frequently.

sqlite3 vacuum,How to use on cordova APP

I have a big problem with the command VACUUM to free the memory from delete´s SQL sentences.
Im making a Cordova Android APP, and i know when i use a DELETE SQL sentence the space of the app don't down,... the space persist like a fragment HardDisk.
Then, i see that VACUUM can compact my DB, but i have a problem!
I use SQLite3, and VACUUM in all sites say that can´t execute in a transaction, like this:
var db = window.sqlitePlugin.openDatabase({name:"maintenance", location:'default'});
db.transaction(function (tx) {
tx.executeSql('VACUUM', [], function (tx, results) {
alert('done');
}, function (tx, error) {
alert('error');
alert(error.message);
});
});
Ok, well, then, if i can't do in a transaction, could u tell me how can i execute a vacuum or auto-vacuum or something similar to compact the BD without write a line command? (remember that its a mobile app)
According to the GitHub Page, you should be able to execute SQL outside of a transaction with db.executeSql:
db.executeSql("VACUUM", [], function(rs) {
// ok
}, function(err) {
// handle error
});

How to make ionic application read in json data from .json file that is local to application

I have a Cordova app that uses the ionic framework. I have many json data files that I put in the www/json folder in my app's file tree. I am using angularJS http calls to access them.
When I test my app in chrome (using "ionic serve" in the terminal) it works fine but when I test it on an android device(nexus 5 with Android 6.0 Marshmallow) it no longer works.
Sample code
function getBookNames() {
return $http.get("..\\bookfolder\\Books.json")
.then(function (data) {//if success than do
return data.data;
}, function (reason) {// if fail than do
// maybe tell the user what happened...
});
}
I have tried adding
var path = "";
if (ionic.Platform.isAndroid()) {
path = "\\android_asset\\www\\";
}
function getBookNames() {
return $http.get(path + "..\\bookfolder\\Books.json")
.then(function (data) {//if success than do
return data.data;
}, function (reason) {// if fail than do
// maybe tell the user what happened...
});
}
when I am debugging the app on my phone I get the following error.
GET file:///android_asset/bookfolder/Books.json net::ERR_FILE_NOT_FOUND
If anyone knows what I am doing wrong or of a better way to access local .json files please let me know. Thanks!
Use slash / character, not backslash \. Also, put bookfolder inside /android_asset/www
$http
.get('/android_asset/www/bookfolder/books.json')
.then(function(response){ return response.data });

Android: Using server-side when working with Parse

Me and my friend are working on an app., and we wish to use Parse.com as our data base from which we can retrieve info.
We can't decide what is the best way to access the data on Parse. For the sake of the example, our app. (i.e. client side) needs something stored on the Parse data base (say some number) - should it directly run the query using the Parse API, or should it make a request to a server side, let it retrieve that number from Parse, and send it back to the client?
We know there's no definite answer, but we couldn't find answer regarding this specific situation. We read this post: When to use client-side or server-side?,
but this not exactly the same case.
I claim that we should try to seperate as much as possible from client side and data bases, and leave these queries run by someone who's in charge (server), where my friend claims this adds unnecessary complication, since it's very natural to use the tools supplied by Parse to access the data base from the client side, without the need for a protocol etc.
We'd appriciate any advice,
Thank you.
In general, go right ahead and make a normal call.
I'd encourage you to do that first in any case, to get everything working on both ends.
Then if necessary go to Cloud Code.
If you are going to do more than one platform (ie iOS and Android), cloud code can be a huge timesaver.
BUT don't forget that for simple calls, cloud code is a waste of time. "Normal" Parse calls are amazingly, incredibly, amazingly, fast and quick to work with.
There is absolutely nothing "wrong" with using normal Parse calls - so do that.
Regarding the question, when do you literally have to use a cloud code call -- you'll know, because you won't be able to do it with a normal call :)
Don't forget very often you can simply use "afterSave" or "beforeSave" in cloud code, to do a huge amount of work. You often don't literally need to go to a "custom call" in cloud code.
Here's a fantastic
Rule of thumb for Parse cloud code --------->
If you have to do "more than one thing" ... in that case you will likely have to make it a cloud code function. If you have to do "three or more things" then DEFINITELY make it a cloud code function.
That's a good rule of thumb.
(Again, as I say, often just an "afterSave" or similar works brilliantly...rather than literally writing a full custom call.)
Here's a typical example of a cloud call that saves 18 billion lines of code in all the platforms covered by the dotcom. First the cloud code...
Parse.Cloud.define("clientRequestHandleInvite", function(request, response)
{
// called from the client, to accept an invite from invitorPerson
var thisUserObj = request.user;
var invitorPersonId = request.params.invitorPersonId;
var theMode = request.params.theMode;
// theMode is likely "accept" or "ignore"
console.log( "clientRequestAcceptInvite called.... invitorPersonId " + invitorPersonId + " By user: " + thisUserObj.id );
console.log( "clientRequestAcceptInvite called.... theMode is " + theMode );
if ( invitorPersonId == undefined || invitorPersonId == "" )
{
response.error("Problem in clientRequestAcceptInvite, 'invitorPersonId' missing or blank?");
return;
}
var query = new Parse.Query(Parse.User);
query.get(
invitorPersonId,
{
success: function(theInvitorPersonObject)
{
console.log("clientRequestFriendRemove ... internal I got the userObj ...('no response' mode)");
if ( theMode == "accept" )
{
createOneNewHaf( thisUserObj, theInvitorPersonObject );
createOneNewHaf( theInvitorPersonObject, thisUserObj );
}
// in both cases "accept" or "ignore", delete the invite in question:
// and on top of that you have to do it both ways
deleteFromInvites( theInvitorPersonObject, thisUserObj );
deleteFromInvites( thisUserObj, theInvitorPersonObject );
// (those further functions exist in the cloud code)
// for now we'll just go with the trick of LETTING THOSE RUN
// so DO NOT this ........... response.success( "removal attempt underway" );
// it's a huge problem with Parse that (so far, 2014) is poorly handled:
// READ THIS:
// parse.com/questions/can-i-use-a-cloud-code-function-within-another-cloud-code-function
},
error: function(object,error)
{
console.log("clientRequestAcceptInvite ... internal unusual failure: " + error.code + " " + error.message);
response.error("Problem, internal problem?");
return;
}
}
);
}
);
If you are new to Parse it's incredibly hard to figure out how to call these from Android or iOS! Here's that one being called from Android ...
this will save you a day of messing about with HashMaps :)
private static void handleInvite( ParseUser invitor, final boolean accepted )
{
String invitorId = invitor.getObjectId();
// you must SEND IDs, NOT PARSEUSER OBJECTS to cloud code. Sucks!
String cloudKode;
cloudKode = (accepted? "accept" : "ignore");
HashMap<String, Object> dict = new HashMap<String, Object>();
dict.put( "invitorPersonId", invitorId );
dict.put( "theMode", cloudKode );
Toast.makeText(State.mainContext, "contacting...", Toast.LENGTH_SHORT).show();
ParseCloud.callFunctionInBackground(
"clientRequestHandleInvite",
dict,
new FunctionCallback<Object>()
{
#Override
public void done(Object s, ParseException e)
{
Toast.makeText(State.mainContext, "blah", Toast.LENGTH_SHORT).show();
// be careful with handling the exception on return...
}
});
}
And here's the same cloud call from iOS ... well for now, until you have to do it in SWIFT
-(void)tableView:(UITableView *)tableView
commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
forRowAtIndexPath:(NSIndexPath *)indexPath
{
int thisRow = indexPath.row;
PFUser *delFriend = [self.theFriends objectAtIndex:thisRow];
NSLog(#"you wish to delete .. %#", [delFriend fullName] );
// note, this cloud call is happily is set and forget
// there's no return either way. life's like that sometimes
[PFCloud callFunctionInBackground:#"clientRequestFriendRemove"
withParameters:#{
#"removeThisFriendId":delFriend.objectId
}
block:^(NSString *serverResult, NSError *error)
{
if (!error)
{
NSLog(#"ok, Return (string) %#", serverResult);
}
}];
[self back]; // that simple
}
Note For the iOS/Swift experience, click to: How to make this Parse.com cloud code call? which includes comments from the Parse.com team. Hope it saves someone some typing, cheers

Categories

Resources