I have a server code to connect to a page that staff use for entering new customers details. The page also inherited from Google Drive Tables with same fields as a page and sheet. Unfortunately, I don't know how to connect my server code to my page so when new data entered and submit button pushed the NewCustomer() function gets called and insert that data into a new row at the end of my spreadsheet.
I just start using appmaker last week and I am sorry if my question is very babyish.
Any help really appreciated.
server code:
function NewCustomer() {
var spreadSheet = SpreadsheetApp.openById("***").getActiveSheet()[0],
dataToBackUp = [],
globalKeys = {
model: ["Channel", "Owner", "INQDate","CustomerName", "CNT", "Contact", "Email",
"Amount", "Status", "TargetDate", "Type", "Transaction", "NoteUpdate"],
label: ["Channel", "Owner", "INQ Date","Customer Name", "CNT", "Contact", "Email",
"Amount", "Status", "Target Date", "Type", "Transaction", "Note Update"],
};
var records = app.models.requests.newQuery().run();
if(records.length >= 1) {
for (var i = 0; i < records.length; i++) {
var newLine = [];
for (var x = 0; x < globalKeys.model.length; x++) {
newLine.push(records[i][globalKeys.model[x]]);
}
dataToBackUp.push(newLine);
if(i === records.length - 1) {
if(dataToBackUp.length >= 1) {
spreadSheet.appendRow(dataToBackUp);
}
}
}
}
}
So, if your only problem is communication between client and server, then you can do it using this snippet:
// onClick button event handler
google.script.run
.withFailureHandler(function(error) {
// TODO: An error occurred, so display an error message.
})
.withSuccessHandler(function(result) {
// TODO: Handle success
})
.myPublicServerSideFunction(param1, param2);
You can read more about client-sever communication by following the links bellow:
https://developers.google.com/apps-script/guides/html/reference/run
https://developers.google.com/appmaker/scripting/client#call_a_server_script
If you want to make your data backup, then you can just go to Settings -> Deployments, select your deployment and Export Data. If you want to automate the process then just switch to Cloud SQL and it will take care about backups for you.
Related
previously, there was the possibility of creating an app services in azure that allowed you to connect an SQL database through the creation of "Easy Tables" but this will be deleted on November 11 (https://aka.ms/easydeprecation), but you can no longer add more tables this way, but you have to do it by the App Service Editor (preliminary version).
I can create the table as the link attached says, the problem is that when I synchronize my data from my xamarin app it says that the resource does not exist or has been removed, that it has been changed or that it is temporarily unavailable.
I think the problem is some configuration or package or extension that I must install in this new app services but I cannot identify it.
My code C #
public async Task SyncAllAsync(bool SyncForce = false)
{
ReadOnlyCollection<MobileServiceTableOperationError> syncErrors = null;
long PendingChanges = CurrentClient.SyncContext.PendingOperations;
try
{
await CurrentClient.SyncContext.PushAsync();
await PatientTable.PullAsync("SyncPatientAsync", PatientTable.CreateQuery());
}
catch (MobileServicePushFailedException exc)
{
if (exc.PushResult != null)
{
syncErrors = exc.PushResult.Errors;
}
}
// Simple error/conflict handling. A real application would handle the various errors like network conditions,
// server conflicts and others via the IMobileServiceSyncHandler.
if (syncErrors != null)
{
foreach (MobileServiceTableOperationError error in syncErrors)
{
if (error.OperationKind == MobileServiceTableOperationKind.Update && error.Result != null)
{
//Update failed, reverting to server's copy.
await error.CancelAndUpdateItemAsync(error.Result);
}
else
{
// Discard local change.
await error.CancelAndDiscardItemAsync();
}
string message = "Error executing sync operation. Item: " + error.TableName + " (" + error.Item["id"] + "). Operation discarded.";
Debug.WriteLine(message);
}
}
}
Patient.json
{
"softDelete" : true,
"autoIncrement": false,
"insert": {
"access": "anonymous"
},
"update": {
"access": "anonymous"
},
"delete": {
"access": "anonymous"
},
"read": {
"access": "anonymous"
},
"undelete": {
"access": "anonymous"
}}
Patient.js
var table = module.exports = require('azure-mobile-apps').table();
// table.read(function (context) {
// return context.execute();
// });
// table.read.use(customMiddleware, table.operation);
The Easy Tables is just a Web API - each table is at https://yoursite.azurewebsites.net/tables/yourtable and the pull operation basically does something like GET https://yoursite.azurewebsites.net/tables/yourtable?filter=(UpdatedAt ge datetimeoffset'some-iso-date'). Enable logging on your Xamarin host (details here plus the end of the same file) to see the actual HTTP requests that are happening.
The error you are receiving is probably a 404. Common issues:
You specified http instead of https in the client
The name of the table is wrong
I developed a SAPUI5 table on frontend having 4 columns, now I need to show the total sum of 1 column. If anyone knows the code related to this please help me
Controller code
onInit: function () {
var oTable = this.byId("producttable");
oTable.addStyleClass("myCustomTable");
//column list item creation
var oTemplate = new sap.m.ColumnListItem({
cells: [
new sap.m.Text({
text: "{Plant}"
}),
new sap.m.Text({
text: "{PlantDesc}"
}),
new sap.m.Text({
text: "{parts: [ {path: 'NetAmount'}, {path: 'currency'}],type: 'sap.ui.model.type.Currency',formatOptions: {showMeasure: false, maxFractionDigits: 0,roundingMode: 'away_from_zero'}}"
})
]
});
var sServiceUrl = "/sap/opu/odata/sap/ZSALES_PLANT001_SRV/";
//Adding service to the odata model
var oModel = new sap.ui.model.odata.ODataModel(sServiceUrl, false);
//Setting model to the table
oTable.setModel(oModel);
oTable.bindAggregation("items", {
path: "/ZSalesheaderSet",
template: oTemplate
});
I am getting the following errors in console
sap-ui-core.js:187 Assertion failed: could not find any translatable
text for key 'Total Sales-Yesterday' in bundle
'./i18n/i18n.properties' Failed to load resource: the server
responded with a status of 503 ()
getSum: function() {
var sum = 0, items = this.getView().byId("tableId").getItems();
for (var i = 0; i < items.length; i++) {
sum = sum + items[i].getBindingContext("urBoundModel").getObject().urColumn
}
return sum;
}
If you have bound the table to a Odata or JSON model. Just Iterate over your items and sum the bound property of the column.
I am trying to update a nested collection using the Patch API. More specifically, consider the following example - a Posts collection:
{
"Title": "Hello RavenDB",
"Category": "RavenDB",
"Content": "This is a blog about RavenDB",
"Comments": [
{
"Title": "Unrealistic",
"Content": "This example is unrealistic"
},
{
"Title": "Nice",
"Content": "This example is nice"
}
]
}
I used the Patch API and Set-based operation docs at http://ravendb.net/docs/client-api/partial-document-updates and http://ravendb.net/docs/client-api/set-based-operations as well as several stackoverflow questions as resources to do a bulk update using set operations and a static index. A requirement is to update the "Title" of a comment only when the previous value was "Nice" and if so, update it to "Bad".
The static index "NicePosts" is defined as:
Map = posts => from post in posts
where post.Comments.Any(comment => comment.Title == "Nice")
select new {post.Title, post.Category}
The bulk patch update command is:
documentStore.DatabaseCommands.UpdateByIndex("NicePosts",
new IndexQuery(),
new[] { new PatchRequest
{ Type = PatchCommandType.Modify,
Name = "Comments",
PrevVal = RavenJObject.Parse(#"{ ""Title"": ""Nice""}"),
Nested = new[]
{
new PatchRequest {Type = PatchCommandType.Set, Name = "Title", Value = new RavenJValue("Bad") },
} }, allowStale: true);
I have some questions regarding this:
1) Is my structure/syntax for the update command correct?
2) I would like the update to be performed on all the records in the collection. Hence I haven't defined the query filter in the IndexQuery Query because the "NicePosts" index already returns the appropriate set. However running this command doesn't update the collection.
3) If I set "allowStale:false" I get a "stale index" error. Before opening my document store session I instantiate the index class and Execute it to persist it to the ravenDB instance. Any ideas whats going wrong here?
Thanks,
EDIT:
Based on ayende's recommendation changed Patch command to:
documentStore.DatabaseCommands.UpdateByIndex("NicePosts",
new IndexQuery(),
new[] {
new PatchRequest {
Type = PatchCommandType.Modify,
Name = "Comments",
Position = 0,
Nested = new[] {
new PatchRequest {Type = PatchCommandType.Set, Name = "Title", Value = new RavenJValue("Bad")},
}
}
}, allowStale: false);
This can now be done using the scripted patch request:
string oldTitle = "Nice";
string newTitle = "Bad";
documentStore.DatabaseCommands.UpdateByIndex("NicePosts",
new IndexQuery(),
new ScriptedPatchRequest
{
Script = #"for (var i = 0; i < this.Comments.length; i++)
if (this.Comments[i].Title == oldTitle)
this.Comments[i].Title = newTitle;",
Values =
{
{ "oldTitle", oldTitle },
{ "newTitle", newTitle },
},
}
);
You can't use the patch command to update values based on the existing value in the array.
You need to specify the actual position.
My app is a list of ToDo's of forms that need to be completed.
When the app is opened, it goes to the server and collects (from a database) a list of forms to be completed.
When you click on a form you can then fill in the data (using LocalStorage proxy) and then save/update the data. The data is stored locally on the device.
As of now : When I open the app again, it collects the same list of ToDo's and overwrites the data in the LocalStorage (ie my filled up forms) with new empty forms and therefore I need to fill them again.
What I want : Instead of overwriting filled up forms I need to only collect those forms that are not already in my localstorage.
My Code :
Store :-
Code:
FMS.stores.onlineTodo = new Ext.data.Store({
model: 'ToDoMod',
proxy: {
id : 'fmsonlinetodo',
type: 'ajax',
url: 'app/data/dummydata.json',
reader: new Ext.data.JsonReader({
root: 'items'
}),
timeout: 2000,
listeners: {
exception:function () {
console.log("I think we are offline");
flagoffline = 1;
//
}
}
}
});
FMS.stores.offlineTodo = new Ext.data.Store({
model : 'ToDoMod',
proxy : {
type : 'localstorage',
id : 'fmsofflinetodo'
}
});
Controller function that loads data into store :
Code:
loadDataInitial : function(){
FMS.stores.onlineTodo.addListener('load', function () {
console.log("I think we are online");
FMS.stores.offlineTodo.proxy.clear();
FMS.stores.onlineTodo.each(function (record) {
FMS.stores.offlineTodo.add(record.data)[0];
});
FMS.stores.offlineTodo.sync();
FMS.stores.offlineTodo.load();
flagoffline = 0;
});
if(flagoffline == 0){
FMS.stores.onlineTodo.load();
}
else{
FMS.stores.offlineTodo.load();
}
},
HELP !!!!!
If I'm not mistaken, you are clearing all of your localStorage records when you use this:
FMS.stores.offlineTodo.proxy.clear();
What you would want to do is use the online store to collect all of the database records and then for each record, query local storage for the same record and if it exists, don't update it.
Basically a version control approach but definitely don't clear the store, you will delete everything in it!
UPDATED:
Here is some sample code:
//load remotestore
remoteStore.load({
scope: this,
callback: function (records, operation, success) {
//get record count
var localCount = localStore.getCount();
if (localCount == 0) {
//iterate each record in remotestore
remoteStore.each(function (record) {
//add record to localStorage
localStore.add(record.copy());
});
//save localstore
localStore.sync();
} else {
//set count var
var count = 0;
//iterate each record in remotestore
remoteStore.each(function (record) {
//reset var
var localRecord = null;
//find matching record in localstore
localRecord = localStore.findRecord('xid', record.data.xid, null, false, false, true);
//if the record exists
if (localRecord) {
//version check
if (record.data.version > localRecord.data.version) {
//remove record from localstore and add new one
localStore.remove(localRecord);
localStore.add(record.copy());
//increment counter
++count;
}
} else {
//add record to localstore
localStore.add(record);
}
});
//save localstore
if (localStore.sync()) {
alert("store saved");
}
//if records were added we need to reload
if (count > 0) {
this.onUpdate();// or whatever your function is.
}
}
}
}); //ends
in your store's load method, just pass addRecords:true, like so:
FMS.stores.onlineTodo.load({addRecords: true});
I am using search option in the list . There is provision to add new items to the list. The problem is that when I add a new item to the list, the list is getting updated , but I cannot search that item through the search field. But after refreshing the browser, we can. But it is not possible to refresh browser each time....... Is there any solution for this problem?
Here is the code I am using to search the list.
xtype: 'searchfield',
placeHolder: 'Search',
name: 'searchfield',
id:'subListSearch',
listeners : {
scope: this,
'focus': function() {
Ext.getCmp('xbtn').show();
},
keyup: function(field) {
var value = field.getValue();
if (!value) {
Store.filterBy(function() {
return true;
});
} else {
var searches = value.split(' '),
regexps = [],
i;
for (i = 0; i < searches.length; i++) {
if (!searches[i]) return;
regexps.push(new RegExp(searches[i], 'i'));
};
Store.filterBy(function(record) {
var matched = [];
for (i = 0; i < regexps.length; i++) {
var search = regexps[i];
if (record.get('Name').match(search)) matched.push(true);
else matched.push(false);
};
if (regexps.length > 1 && matched.indexOf(false) != -1) {
return false;
} else {
return matched[0];
}
});
}
}
}
There is also some other problems. I using some provision to filter the list. But when I uses the search option, it is searching through the entire list, not the filtered list.why?
Thanks
Arun A G
Thanks for responding to my question .
The problem is fixed with bindStore() method. Earlier I was doing load() method to render the new data into the store. But we can not search the last entered item with this method. After binding the Changed store into the list with bindStore() method, the issue was solved.