I have a very basic create db statement like this:
var instance = openDatabase(databaseModel.name, databaseModel.version, databaseModel.alias, databaseModel.timeout); //Open a DB based on Name and Version Number
insertTable: function(insertStatement, dataArray) {
var deferred = q.defer();
try {
var request = _db.instance.transaction(function(tx) { tx.executeSql(insertStatement, dataArray); });
deferred.resolve(request);
} catch (e) {
deferred.reject(new Error(e));
}
return deferred.promise;
}
};
This works great for opening a database and adding some records but when I close the browser or the Cordova app, the database is gone.
What am I doing wrong ?
Related
i've to edit a web application already existing that i don't know at all.
into a web page this code create an unique number:
Fingerprint2.get(function (components) {
try {
var values = components.map(function (component) { return component.value });
var murmur = Fingerprint2.x64hash128(values.join(''), 31);
$("#id-fingerprint").val(murmur);
} catch (err) {
}
});
our customers are working on cloned pc, same hardware and software, so it happens two different users generate the same unique number.
my purpose is to add username to existing code.
is this a good way to do it?
Fingerprint2.get(function (components) {
try {
var values = components.map(function (component) { return component.value });
var username = $("#username").val();
values.push(username);
var murmur = Fingerprint2.x64hash128(values.join(''), 31);
$("#id-fingerprint").val(murmur);
} catch (err) {
}
});
You can add a custom component, you can learn more in the Extending FingerprintJS guidelines. Simply put, you just need to add your id into the components object.
const result = await fp.get()
const components = {
...result.components,
foo: username
}
const visitorId = FingerprintJS.hashComponents(components)
I am new to AppMaker but I have developer experience.
The application is a Project Tracker Application
What I expect to happen: When creating a project the user uses a User Picker to select the users associated with that project. When the project is created I want to email the users associated with that project.
The issue: On clicking the Add button addProject(addButton) client script function is called.
Inside this function sendEmailToAssignees(project, assignees) is called which should reach out to the Server script and run the notifyAboutProjectCreated(project, assignees) but that is not happening.
Things to know: With logging I never reach 'Trying to send email' so I seem to never reach my server script. Also, On client script when I comment out sendEmailToAssignees function everything runs smooth. I have looked at this documentation as a resource so I feel my implementation is okay. https://developers.google.com/appmaker/scripting/client#client_script_examples
The final error message I get is:
Failed due to illegal value in property: a at addProject
(AddProject:110:24) at
AddProject.Container.PanelAddProject.Form1.Spring.ButtonAdd.onClick:1:1
Am I missing something here? Any help would be greatly appreciated. Thank you!
Client Script
function sendEmailToAssignees(project, assignees) {
google.script.run
.withSuccessHandler(function() {
console.log('Sending Email Success');
}).withFailureHandler(function(err) {
console.log('Error Sending Email: ' + JSON.stringify(err));
})
.notifyAboutProjectCreated(project, assignees);
}
function addProject(addButton) {
if (!addButton.root.validate()) {
return;
}
addButton.datasource.createItem(function(record) {
var page = app.pages.AddProject;
var pageWidgets = page.descendants;
var trainees = pageWidgets.AssigneesGrid.datasource.items;
var traineesEmails = trainees.map(function(trainee) {
return trainee.PrimaryEmail;
});
record.Assignee = traineesEmails.toString();
var assignees = traineesEmails.toString();
var project = record;
updateAllProjects(record);
console.log('update all projects done');
sendEmailToAssignees(project, assignees);
console.log('Send Email done');
if (app.currentPage !== app.pages.ViewProject) {
return;
}
gotoViewProjectPageByKey(record._key, true);
});
gotoViewProjectPageByParams();
}
Server Script
function notifyAboutProjectCreated(project, assignees) {
console.log('Trying to send email');
if (!project) {
return;
}
var settings = getAppSettingsRecord_()[0];
if (!settings.EnableEmailNotifications) {
return;
}
var data = {
appUrl: settings.AppUrl,
assignee: project.Assignee,
owner: project.Owner,
startDate: project.StartDate,
endDate: project.EndDate,
jobType: project.Type,
jobId: project.Id
};
// Email Subject
var subjectTemplate = HtmlService.createTemplate(settings.NotificationEmailSubjectJob);
subjectTemplate.data = data;
var subject = subjectTemplate.evaluate().getContent();
// Email Body
var emailTemplate =
HtmlService.createTemplate(settings.NotificationEmailBodyJob);
emailTemplate.data = data;
var htmlBody = emailTemplate.evaluate().getContent();
console.log('About to send email to:', assignees);
sendEmail_(null, assignees, subject, htmlBody);
}
The reason you are getting this error is because you are trying to pass the client "project record" to the server. If you need to access the project, then pass the record key to the server and then access the record on the server using the key.
CLIENT:
function sendEmailToAssignees(project, assignees) {
var projectKey = project._key;
google.script.run
.withSuccessHandler(function() {
console.log('Sending Email Success');
}).withFailureHandler(function(err) {
console.log('Error Sending Email: ' + JSON.stringify(err));
})
.notifyAboutProjectCreated(projectKey , assignees);
}
SERVER:
function notifyAboutProjectCreated(projectKey, assignees) {
console.log('Trying to send email');
var project = app.models.<PROJECTSMODEL>.getRecord(projectKey);
if (!project) {
return;
}
//Rest of the logic
}
The project record object in the client is not the same as the project record object in the server; hence the ilegal property value error.
i have the following problem. I designed my litesql database over 'DB Browser for SQLite' and I'm stuck as soon as a query gets executed. The functions I am exporting are getting imported and used in nativescript-vue.
Webpack also copies the database with *.sqlite ending to the device. The android version I use is 9.
The way I initialize my db is;
var Sqlite = require("nativescript-sqlite");
var db;
export function init() {
if (!Sqlite.exists("test.sqlite")) {
Sqlite.copyDatabase("test.sqlite");
}
new Sqlite("test.sqlite", function(err, dbConnection) {
if (err) {
console.log(err);
return;
}
db = dbConnection;
console.log("connection successful")
});
}
After running the function console shows 'connection successful'. The database is placed in the root of the app folder. That way it should pull the database?
Besides I got another question. How could I hide the database in the production?
So the way I execute the query is:
export function xxxx(**parameter**) {
db.execSQL(
"select random_id from random_table where some_id = ?",
**parameter**,
function(err, result) {
console.log("result 1: " + result + " err: " + err);
}
);
}
The output is:
JS: 'result 1: null err: null'
I'm not even sure if it opens the database in the right way?
If you just want to export DB file from Android / iOS, you may use nativescript-share-file plugin and pass the right path.
Android
const filePath = application.android.context
.getDatabasePath("your-db-name.sqlite")
.getAbsolutePath();
new ShareFile().open({
path: filePath,
});
For iOS the path will be different,
iOS
const filePath = knownFolders.documents().getFile("your-db-name.sqlite").path;
new ShareFile().open({
path: filePath,
});
I have a project on Ionic where I need to render some information of the database in the home page, something like a TODO program.
I already have some information on the database and I'm trying to render the list of items but I have the next problem:
First the home page is loaded without any result
Then the data from the database is loaded and printed on the screen
The problem is I want the view to wait until the database info is loaded until showing anything, I'm wondering if I can use some kind of loading icon.
I've followed the answer here: Open database before main controller is called in Ionic and SQlite
I have the database initialization working but as I've said, the data is loaded after the view is rendered.
I've tried using $ionicLoading but I didn't get any good result
This is my view:
.controller('homeCtrl', function ($scope, $state, $cordovaSQLite, DB) {
$scope.$on('$ionicView.enter', function() {
tasks = []
var query = "SELECT * FROM task;";
$cordovaSQLite.execute(DB.db, query, []).then(function(results) {
if(results.rows.length > 0) {
for (i=0; i<results.rows.length; i++){
console.log("SELECTED -> " + results.rows.item(0).title);
$scope.tasks.push(results.rows.item(i))
}
} else {
console.log("No results found");
}
}, function (err) {
$scope.tasks = [];
console.error(err);
});
$scope.tasks = tasks;
});
})
This is a video example of the issue I'm having right now:
https://youtu.be/H2fUYQuV3xg
Finally I found a solution following the advice of using resolve in my routes.
.state('home', {
url: '/',
templateUrl: 'templates/home.html',
controller: 'homeCtrl',
resolve: {
tasks: function(DB) {
return DB.getTasks();
});
}
}
})
I have a factory called DB where I have some functions to retrieve data from the database. On this example I load the tasks before entering on the URL using DB.getTasks()
To load the variable tasks resolved on the route I have to add the variable name on the function like this:
app.controller('homeCtrl', function (tasks) {
$scope.tasks = tasks;
})
I'm using SimpleSchema and Collection2.
Before pushing a new version of my app, I'd like to check if any documents would be invalid with the new schema. Is there an automated way to do this?
Or a command line utility?
How do you release new versions with altered schemas?
Thanks!
Mike
From your meteor app on either the client or server (assuming you have access to all the documents you want to check on the client):
MyCollection.find().forEach(function(doc){
check(doc,MyCollectionSchema);
});
You'll probably also want to log the doc and its _id on failures so you can go fix them.
Both SimpleSchema and Collection2 have validating methods.
For SimpleSchema, here are their example codes: https://github.com/aldeed/meteor-simple-schema#validating-data
For Collection2, check the sections starting from Validation Contexts https://github.com/aldeed/meteor-collection2#validation-contexts
I followed #michel's advice and made this server-side route for checking collections.
This is pretty dangerous, because it's cleaning and saving your data. That means it's erasing fields. Probably you didn't want those fields which is why you removed them from your schema, but also, it may be a bug. So caveat emptor cowboy. Obviously, this shouldn't be on a production server.
They can be checked using an url like this:
http://127.0.0.1:4000/v/users
Response:
{
"ok": 1
}
The route:
skipUpdatedAt = true;
Router.route('validate', {
path: '/v/:collection',
where: 'server',
action: function() {
var res = this.response;
var collections = {
users: Meteor.users,
puppies: Puppies,
unicorns: Unicorns,
rainbows: Rainbows,
};
var c = collections[this.params.collection];
if (!c) {
res.statusCode = 404;
return res.end('not found');
}
var s = c.simpleSchema();
var ret = { ok: 0 };
c.find().forEach(function(doc){
var id = doc._id;
try {
s.clean(doc);
check(doc,s);
c.update(id, doc, {validate: false});
ret.ok += 1;
} catch (e) {
ret[id] = {
doc: doc,
error: e.toString(),
};
console.log('=============ERROR');
console.log(doc);
console.log('-------------');
console.log(e);
}
});
res.statusCode = 200;
if (Object.keys(ret).length) res.statusCode = 500;
res.end(JSON.stringify(ret, null, 2));
}
});