1

I'm confused about how widget binding works, according to google document, a two-way binding works:
1. when use UI widget to update model data to server side.
2. "any change to a name on the server automatically updates the text displayed in the text box" However, this is not what I see, I cannot see that widget (ex. textbox) value changes following a server side data update.

I did a test in the official sample Registration Form, there is a list of all Registration items. My testing setting is to update the first entry (Id=1)'s email address by entering a new email and have two buttons to update info: button 'CHANGE_CLIENT' uses a client script, and button 'CHANGE_SERVBER' uses a server script.

CHANGE_CLIENT code is client script in onClick() event:

var item = widget.datasource.items.filter( a => a.Id == 1 )[0];
item.Email = widget.parent.descendants.TextBox1.value;

Result:
a click on the button, new value is updated into list's 1st item as expected. A screenshot for info

CHANGE_SERVER code has both client script and server script:
client script:

function c(newvalue) {
 google.script.run.withSuccessHandler(function() {console.log('ok');}).withFailureHandler(function() {console.log('nono');}).change(newvalue); 
}

server script:

function change(newvalue) {
 var record = app.models.Registration.getRecord('1');
  record.Email = newvalue;
  app.saveRecords([record]);
}

Result:
a click on the button succeeded ('ok' in log from onSuccessHandler), but textbox value didn't change, need another refresh of page to have datasource re-loaded to see the new value. That is not what binding explained by Google's document "any change to a name on the server automatically updates the text displayed in the text box". A screenshot for info

I expect that two-way binding works as google's statement, and my server codes update can lead to an automatic UI value change. As I didn't see this happening, I have to manually re-load datasource, I hope this is not necessary and want to know how to have this server triggered binding value update works, any thought or suggestion is appreciated.

UPDATE:

I did an additional test and have more finding: server side data update can be see automatically on client side when:

  • a modification on modelA's value from a client side (input edit or client script)
  • a server side further data update via data events, ex. onAfterSave()
  • the related data update on modelA's actual/selected item record will be shown on UI automatically
  • but, relation model modelB's updated value will not change on UI before a page/datasource reload. My testing shown in above screenshot, a modelA with UnitPrice, Quantity and TotalPrice, and its one2one relation modelB with doubleSum = TotalPrice * 2. And I set Server Script in modelA's onAfterSave() data event:
record.TotalPrice = record.UnitPrice * record.Quantity;
var doublePrice = record.TotalPrice * 2;
var recordD = record.double;
recordD.doubleSum = doublePrice;
app.saveRecords([record,recordD]);

Once an update on UnitPrice or Quantity, modelA's TotalPrice and modelB's doubleSum value updated by Server Script, while modelA's TotalPrice updated on UI automatically, modelB's doubleSum requires a page/datasource reload to update on UI.
It looks that Appmaker only keep current item's own data (not relation model's) synchronised between client UI and server in real time. IOW, only SIMPLE binding can see two-way binding in case an update triggered by a change on current item's value from client side.

Albert
  • 126
  • 6

1 Answers1

2

The concept of two way binding is misleading. In your example for the client change, that's the two way binding. Let me explain in detail...

In the table, item number one has the email new@g.com. That email value is shown by a Label widget that is binded to the email field on the server. When you click the CHANGE_CLIENT button, you change the information on the client first. That's why the Label widget that is on the table row get's updated, then it updates on the server. That is what is meant by

Additionally, any change to a name on the server automatically updates the text displayed in the text box.

That is because it gives the effect that it changed on the server and afterwards on the client. In other words, the text box that you are using to put the new value, does not uses binding, hence you need to use client script to update the value on the client which then triggers an event to update the value on the server.

Now, when you perform the change using server script, the data in the client never updates because the record needs to reload. For that your script should look like this:

function c(newvalue) {     
    google.script.run.withSuccessHandler(function(){
        console.log('ok');
        app.datasources.TheDatasource.item._reload();
    }).withFailureHandler(function(err){
        console.log(err);
    }).change(newvalue); 
}

In reality, the two way binding only refers to changes that happen in the client and reflects on the server. I believe the documentation wording should change to avoid confusion.

Morfinismo
  • 4,985
  • 4
  • 19
  • 36
  • 1
    thanks for your explanation, so, what I got: 1. UI input or client script triggered data change will show automatically on UI and synced/pushed to server side database. 2. server script leading data change requires a re-load of datasource to have it showing on UI. I see the importance of datasource re-loading in other scenario, for example, in above mentioned list, datasource is descendant by Id, and the new item will be attached at the end of list regardless of sorting and paging setting. I posted an issue request to Google https://issuetracker.google.com/issues/139121048 – Albert Aug 08 '19 at 17:15
  • I don't know if that is possible but it would be cool. Then there would be no need to integrate firebase like in the answer I explained here https://stackoverflow.com/a/50126521/5983596 – Morfinismo Aug 08 '19 at 17:24
  • Thanks for sharing that idea datasource sync performance. Meanwhile, I updated an additional testing in the question, it shows a two-way binding can be seen under limits. – Albert Aug 09 '19 at 10:51