Using JSDOs to create mobile and web clients : Accessing standard CRUD and Submit operations : Create operation example : Client JavaScript code: Create
  
Client JavaScript code: Create
The following examples illustrate calling add( ) on a table reference to create a record in JSDO memory, then calling saveChanges( ) on the dsCustomer JSDO without Submit to add the new record to the server database (along with any other pending record-change operations), and using both an afterCreate event handler and a returned Promise object to handle the results.
This example uses simple error handling to log the contents of each error object returned by the JSDO getErrors( ) method:
/* subscribe to event */
dsCustomer.ttCustomer.subscribe('afterCreate', onAfterCreate);

/* some code that adds a record and sends it to the server */
var jsrecord = dsCustomer.ttCustomer.add( {State : 'MA'} );

/* some other JSDO memory record changes . . . */

dsCustomer.saveChanges(false).done( /* Successful method execution */
    function( jsdo, success, request ) {
        /* all resource operations invoked by saveChanges() succeeded */
        /* for example, process all records based on their State value */
        jsdo.ttCustomer.foreach( function(jsrecord) {
            if (jsrecord.data.State === 'MA') {
                /* process all records for the state of MA . . . */
            }
            if (jsrecord.data.State === 'VT') {
                /* process all records for the state of VT . . . */
            }
        });

    }).fail( /* Unsuccessful method execution */
    function( jsdo, success, request ) {
        /* one or more resource operations invoked by saveChanges() failed */
        var lenErrors,
errors,
errorType;

/* handle all operation errors */
errors = jsdo.ttCustomer.getErrors();
lenErrors = errors.length;
for (var idxError=0; idxError < lenErrors; idxError++) { /* Each error */
console.log(JSON.stringify(errors[idxError]));
}
    });

function onAfterCreate (jsdo , record , success , request ) {
    /* check for errors on any Create operation */
    if (success) {
        /* do the normal thing for a successful Create operation.
           for example, process new record according to its State value  */
        switch (record.data.State ) {
            case 'MA':
                /* process a record created for MA . . . */
                break;
            case 'VT':
                /* processs a record created for VT . . . */
                break;
            default:
                /* process a record created for any other state . . . */
                break;
        }
    }
    else {
        /* all error messages handled by the Promise.fail() callback */
}
};
This example is identical to the previous one but with more complex error handling to log the contents of each error object using more readable output:
/* subscribe to event */
dsCustomer.ttCustomer.subscribe('afterCreate', onAfterCreate);

/* some code that adds a record and sends it to the server */
var jsrecord = dsCustomer.ttCustomer.add( {State : 'MA'} );

/* some other JSDO memory record changes . . . */

dsCustomer.saveChanges(false).done( /* Successful method execution */
    function( jsdo, success, request ) {
        /* all resource operations invoked by saveChanges() succeeded */
        /* for example, process all records based on their State value */
        jsdo.ttCustomer.foreach( function(jsrecord) {
            if (jsrecord.data.State === 'MA') {
                /* process all records for the state of MA . . . */
            }
            if (jsrecord.data.State === 'VT') {
                /* process all records for the state of VT . . . */
            }
        });

    }).fail( /* Unsuccessful method execution */
    function( jsdo, success, request ) {
        /* one or more resource operations invoked by saveChanges() failed */
        var lenErrors,
errors,
errorType;

/* handle all operation errors */
errors = jsdo.ttCustomer.getErrors();
lenErrors = errors.length;
for (var idxError=0; idxError < lenErrors; idxError++) { /* Each error */
switch(errors[idxError].type) {
case progress.data.JSDO.DATA_ERROR:
errorType = "Server Data Error: ";
break;
case progress.data.JSDO.RETVAL:
errorType = "Server App Return Value: ";
break;
case progress.data.JSDO.APP_ERROR:
errorType = "Server App Error #"
+ errors[idxError].errorNum + ": ";
break;
case progress.data.JSDO.ERROR:
errorType = "Server General Error: ";
break;
case default:
errorType = null; // Unexpected errorType value
break;
}
if (errorType) { /* log all error text
console.log("ERROR: " + errorType + errors[idxError].error);
if (errors[idxError].id) { /* error with record object */
console.log("RECORD ID: " + errors[idxError].id);
/* possibly log the data values for record with this ID */
}
if (errors[idxError].responseText) {
console.log("HTTP FULL TEXT: "
+ errors[idxError].responseText);
}
}
else { /* unexpected errorType */
console.log("UNEXPECTED ERROR TYPE: "
+ errors[idxError].type);
}
}
    });

function onAfterCreate (jsdo , record , success , request ) {
    /* check for errors on any Create operation */
    if (success) {
        /* do the normal thing for a successful Create operation.
           for example, process new record according to its State value  */
        switch (record.data.State ) {
            case 'MA':
                /* process a record created for MA . . . */
                break;
            case 'VT':
                /* processs a record created for VT . . . */
                break;
            default:
                /* process a record created for any other state . . . */
                break;
        }
    }
    else {
        /* all error messages handled by the Promise.fail() callback */
}
};
This sample code:
*Subscribes a callback function, onAfterCreate, to the afterCreate event to enable error-checking and manipulation of the new record after the Create operation completes on the server. This includes client processing of the record based on its State field value. This callback ignores and defers all error handling to the fail() callback registered on the Promise returned by saveChanges( ). (Typically, you code similar afterUpdate and afterDelete event callbacks for the app as required.)
*Adds a record to the ttCustomer table, with an initial value of 'MA' for the State field. (Note: The table reference can be omitted if ttCustomer is the only temp-table in the dsCustomer ProDataSet.)
*Calls saveChanges(false) (without Submit) to invoke all pending Data Object operations one record at a time on the server, including creation of the new record with its State field set to 'MA', and thereby synchronizes the content of JSDO memory with the server database for one record-change operation at a time across the network. A returned Promise object handles the overall success or failure of saveChanges( ) after all pending Create, Update, and Delete (CUD) operations complete, which includes successful processing of all client records based on their State field value.
For a successful saveChanges( ) invocation without Submit, the done() callback processes all client records for selected State field values. For an unsuccessful saveChanges( ) invocation, the fail() callback handles all error messages returned in response to invoking each CUD operation across the network.
Note: This example takes advantage of the default setting of the JSDO autoApplyChanges property (true), which automatically accepts or rejects changes to JSDO memory based on whether the CUD operation was successful. Note also that errors returned by getErrors( ) remain available until the next call to fill( ) or saveChanges( ).
Note: Any event handler callback functions (such as onAfterCreate) always execute before any registered Promise callback methods (such as done()). For an invocation of saveChanges( ) without Submit, the event callbacks execute after each CUD operation completes and returns its results from the server, and the appropriate registered Promise callbacks execute only after all results from these CUD operations have been returned from the server, which allows the results of all CUD operations to be processed together on the client.