Search code examples
javascriptgoogle-app-maker

How to catch an error on saveChanges - Google App Maker


I'm trying to catch an error when creating a new record to a data source. (The data source is set to only accept unique values on one of the fields.)

When attempting to force an error the client side script runs and displays the final popup stating that a new record was created successfully. Instead of displaying the popup to state an error creating the record has occurred.

I spoke with one of our senior devs and he explained the issue is due to saveChanges running asynchronously. (The call to save changes runs without any error and only after it completes does it return an error.)

So my question is how do I catch an error after saveChanges completes and display a popup. (If record created successfully or failed.)

My Code:

//Creates New Stores
function createNewStores() {  

var newCert = '{"ShopCertificates":[{"Certificate_ID":"","Certificate_Name":"","Valid_From":"","Valid_To":"","Renewal_Date":"","Date_Applied_For_Renewal":"","Date_Compliance_Received":"","Date_Compliance_Issues_Resolved":"","Compliance_Notice_Date":"","Certificate_URL":""}]}';

//Get the Datasource, set it to create mode and create a new blank item.
var createDatasource = app.datasources.Stores.modes.create;
var draft = createDatasource.item;

//Get the selected values from the page.
var brand = app.pages.A_Add_Store.descendants.Dropdown_Brand_Selector.value;
var division = app.pages.A_Add_Store.descendants.Dropdown_Division_Selector.value;
var storeName = app.pages.A_Add_Store.descendants.Dropdown_Stores_Selector.value;

//Set the values of the draft record to be the values entered in the form.
draft.StoreId = parseInt(storeName);
draft.Brand = brand;
draft.Division = division;
draft.Store_Name = storeName;
draft.Cert_JSON = newCert;

//Create the new record in the datasource and save changes to the datasource.
try{
createDatasource.createItem();
app.datasources.Stores.saveChanges();
}
catch(err){
app.popups.Error_Store_Already_Exists.visible = true;
}

//After record is created set values in form to null.
app.pages.A_Add_Store.descendants.Dropdown_Brand_Selector.value = null;
app.pages.A_Add_Store.descendants.Dropdown_Division_Selector.value = null;
app.pages.A_Add_Store.descendants.Dropdown_Stores_Selector.value = null;

//Display Popup stating store has been added.
app.popups.New_Store_Added.visible = true;
}

Solution

  • Assuming that your Stores datasource is set to 'Manual Save' mode the following should work:

    Replace this section of code:

    try{
    createDatasource.createItem();
    app.datasources.Stores.saveChanges();
    }
    catch(err){
    app.popups.Error_Store_Already_Exists.visible = true;
    }
    

    With this:

    createDatasource.createItem();
    app.datasources.Stores.saveChanges({
      success: function() {
        app.popups.New_Store_Added.visible = true;
      },
      failure: function() {
        app.popups.Error_Store_Already_Exists.visible = true;
      }
    });
    

    If your datasource is set to auto save then the saveChanges() function will get ignored and you will not be able to pass a call back in that function. Please reference the asynchronous operations section in the documentation here https://developers.google.com/appmaker/scripting/client#asynchronous_operations.

    If this doesn't work for you or you are unable to use this to figure out your code please let me know.