What callback function do I use in the client script [duplicate] - google-app-maker

This question already has answers here:
Generating an email list from AppMaker Database
(2 answers)
Closed 5 years ago.
I am trying to query items on a model in my app, and I am currently able to do that in the Server Script. However, I don't know how to return the items that I queried back to the Client Script side.
This is the function that I am using on the Server script:
function spouseRecord(){
var query = app.models.Dependent.newQuery();
query.filters.Relationship._equals = "Spouse";
var spouse = query.run();
var payload = {
SpouseName: spouse[0].LastName + " " + spouse[0].FirstName + " " + spouse[0].MidName,
SpouseSSN: spouse[0].SSN,
SpouseDateofBirth: spouse[0].BirthDate.toLocaleDateString(),
SpouseSex: spouse[0].Sex,
};
return payload;
}
I think that this function is OK as is. My problem is on the client side. I want to obtain the object payload. I am using this function.
var payload = google.script.run.withSuccessHandler().spouseRecord();
I don't know what I need to place between the parenthesis of withSuccessHandler. Can anyone help me?
Thank you.

You need a client script function that will handle the server script results. Your code should look something like this:
function showPayload(payload){
console.log(payload);
}
var payload = google.script.run.withSuccessHandler(showPayload).spouseRecord();
This question seems to be a duplicate of this one Generating an email list from AppMaker Database

Related

Cloud Functions retrieve List from Firebase Database

I'm triggering a Cloud Function using Http Request.
The issue is to retrieve the entire List of Objects I have, without an event to then loop through them.
The List is under the account/userId Node.
Here is what I use but I get nothing:
return admin.database().ref('/account/' + userId).once('value').then(function (snap) {
let data = snap.val();
}
Without seeing your database structure it is a bit difficult to write an answer and be 100% sure it is a correct one, but the following should do the trick:
return admin.database().ref('/account/' + userId).once('value').then(function (snap)
snap.forEach(function(child) {
const childKey = child.key; // <- here you get the key of each child of the '/account/' + userId node
console.log(childKey);
const childVal = child.val(); // <- and here you get the values of these children as JavaScript objects
console.log(childVal);
});
});
In case this is not exactly what you are looking for, please update you Question with your database structure and the entire code of your Cloud Function.

Firebase function access not related data [duplicate]

This question already has an answer here:
How to read any data from database on its write trigger on one of its child in firebase functions?
(1 answer)
Closed 5 years ago.
I'm searching for a way when I can access database elements not related to my trigger data in firebase functions.
As I see I can set(...) things on other elements but unfortunately I can't just read the values out of the elements, for example this doesn't work:
event.data.adminRef.root.child('bettings/'+matchId+'/begin_at').val()
I know about the 'proper way' to get those things, which is like:
var match = event.data.adminRef.root.child('bettings/' + matchId + '/begin_at');
match.once('value',function(snapshot){
var alma = snapshot.val();
console.log('alma val');
console.log(alma);
});
But I hope there is a better/easier way then write such codes all the time I need something out of my current scope.
Update: it is not a duplicate of How to read any data from database on its write trigger on one of its child in firebase functions? !
I know about ....once(..), and that I can access the values through promises but I need a much more quicker way, because sometimes it takes about 10 seconds, which is really slow and the user won't get the response in time!
Here is an example where you access data from a specific database node and perform a task with the value jobowner:
let jobRef = admin.database().ref(`/jobs/${jobid}`);
const jo = jobRef.child("owner").once('value');
return Promise.all([jo]).then(r => {
const jobowner = r[0];
const promises = [];
let key = admin.database().ref(`/jobowners/${jobowner}`).set({
value: 'test',
other: false
});
promises.push(room);
return Promise.all(promises);
});

Deleting data from Drive Tables and automatically re-importing new data

I need help with trying to understand how to delete all data from a table and then try to automatically import a new sheet with data into the newly cleared down table.
I'm currently trying the unload() method client side but that doesn't seem to cleardown my tables
function ClearDown(){
app.datasources.P11d.unload(function(){});
console.log('Finish Delete');
}
I've also tried to create a server side function, which also doesn't appear to work
function ClearTable(){
var records = app.models.P11d.newQuery();
// records.run();
console.log('Server Function Ran');
app.deleteRecords(records.run());
}
This is ran from a client side function:
function Delete(){
google.script.run.withSuccessHandler(function(result){
}).ClearTable();
console.log('Function Ran');
}
Again this is all to no avail
With the import side I've tried to do the below:-
Client Side:
function ImportData(){
console.log('Begin');
var ss = SpreadsheetApp.openById('SHEET ID');
var values = ss.getSheetByName('P11d').getDataRange().getValues();
var ssData = [];
// app.datasources.P11d.unload(function(){});
for (var i = 0; i<values.length; i++){
var newRecord = app.models.P11d.newRecord();
// add all fields to the new record
newRecord.Reg_Number = values[i][0];
newRecord.Reg_Date = values[i][1];
newRecord.Model_Description = values[i][2];
newRecord.P11d_Value = values[i][3];
newRecord.EngineSize = values[i][4];
newRecord.Fuel = values[i][5];
newRecord.CO2 = values[i][6];
newRecord.SIPP = values[i][7];
newRecord.GTA_Code = values[i][8];
newRecord.Type = values[i][9];
ssData.push(newRecord);
// console.log(newRecord.MODEL_FIELD);
}
console.log('Finished');
// return the array of the model.newRecord objects that would be consumed by the Model query.
}
Please can someone help with this, at the moment the way the data is sent over to me adding new stuff into the Drive Table is causing many duplicates.
Thanks in advance,
You can delete all records, import, and read from a spreadsheet using the AMU Library
Copy and paste the server and client scripts into your app.
I'm sure that will make it much easier!
To delete all the data in a model using this:
Button onClick:
google.script.run.AMU.deleteAllData('ModelName');
The correct way to delete records on the server is:
app.models.MODEL_NAME.deleteRecords(key_array);
datasource.unload() simply unloads the widget on the client. It does not affect the database records.
A better way to write your records query on the server is:
var query = app.models.MODEL_NAME.newQuery();
query.filters.your_filter_here;
var records = query.run();
Note that you cannot return a single record or an array of records from anything but a calculated model function without using a function posted here. (You can return a single field of a record using stringify for any json data.)
I am currently working on a solution to create datasource independent tables needed in App Maker.
For the delete function on the server try to change your code just a little bit, this function at least used to work for me, however I have not needed to use it in some time.
function ClearTable(){
var records = app.models.P11d.newQuery().run();
console.log('Server Function Ran');
app.deleteRecords(records);
}

data not set using .set on Firebase

First question here,
I am trying to follow the startup guide on the Firebase, but as I am trying to click the send button, the data is not transferred to the data server.
Here is the code:
var yjDataRef = new Firebase('https://yjyc-signup.firebaseio.com/');
var name = document.getElementById('name');
var email = document.getElementById('email');
var submitBtn = document.getElementById('submit');
nameRef = yjDataRef.child('nameRef');
submitBtn.addEventListener('click' function() {
nameRef.set(name: 'name');
});
I have called all of them but still, the data does not transferred to the data center.
Thank you so much for your help.
I believe you need a comma after 'click'.
https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener

Meteor multiplayer game clients get out of sync - how to debug?

I've built a simple real-time multiplayer math game in Meteor that you can try out here: http://mathplay.meteor.com
When playing locally (using different browsers), everything works fine. But when I play over the Internet with friends, the clients often get out of sync: a question listed as active for one player is actually already solved by another player.
My guess is that some code that should be server-only gets executed on one of the clients instead. Any suggestions on how to debug this behavior?
Here is what happens on the client when user submits an answer:
Template.number_input.events[okcancel_events('#answertextbox')] = make_okcancel_handler({
ok: function (text, event) {
question = Questions.findOne({ order_number: Session.get("current_question_order_number") });
if (question.answer == document.getElementById('answertextbox').value) {
console.log('True');
Questions.update(question._id, {$set: {text: question.text.substr(0, question.text.length - 1) + question.answer, player: Session.get("player_name")}});
callGetNewQuestion();
}
else {
console.log('False');
}
document.getElementById('answertextbox').value = "";
document.getElementById('answertextbox').focus();
}
});
callGetNewQuestion() triggers this on both client and server:
getNewQuestion: function () {
var nr1 = Math.round(Math.random() * 100);
var nr2 = Math.round(Math.random() * 100);
question_string = nr1 + " + " + nr2 + " = ?";
question_answer = (nr1 + nr2);
current_order_number = Questions.find({}).count() + 1;
current_question_id = Questions.insert({ order_number: current_order_number, text: question_string, answer: question_answer });
return Questions.findOne({_id: current_question_id});//current_question_id;
},
Full source code is here for reference: https://github.com/tomsoderlund/MathPlay
Your problem lies with this:
callGetNewQuestion() triggers this on both client and server
This will generate a different _id because of the timing difference, as well as a different question which will then get replaced with that one that the server generated. However, this might not always be the case. This makes it very easy to let things get out of sync, simply because your client is generating its own stuff.
You'll need to figure out a better approach at making sure the client generates the same data as the server. Which can be done by making sure that a random number generator is seeded the same way and thus would give the same random numbers every time. This will resolve any flickering because the values are different.
Then, for the actual bug you might not want to do this:
return Questions.findOne({_id: current_question_id});
But do this instead (only on the client, do nothing on the server):
Session.set('current_order', current_order_number); // ORDER! Not the _id / question_id.
That way, you can put the following in a template helper:
return Questions.findOne({ order_number: Session.get('current_order') });
In essence, this will work in a reactive way on the Collection and not dependent on the return value.

Resources