How to do a validation that requires an API call

I want to add a validation to make sure the email address added to a record is unique.  This, of course, requires an API call to go check the current email address to all the others.  The problem is, in my validation function, by the time the API call returns the record is saved already.

I am looking to see if anyone else has already conquered this.  I have already tried changing the "{async: true}" to "{async: false}".  Not sure what that does but it doesn't fix this.

For example if this were my function (maybe better written in the end), by the time the 'Success' function was triggered, the record is already saved.

_doValidateEmail: function (evt) {
     // let emails = $(".existingAddress").val(),
     let self = this,
            id = this.model.get('id'),
            emailField = this.$(evt.currentTarget);
        $(".newEmail, .existingAddress").each(function () {
             let emailAddress = $(this).val(),
                urlString = 'uniqueEmail/' + id + '/' + emailAddress;
            if (!self.isEmptyS2S(emailAddress)) {
                 if (emailAddress.indexOf('.') > 0) {
                      console.log('Testing email address: ' + emailAddress);
                      console.log('URL: ' + urlString);
                      App.api.call('GET', App.api.buildURL(urlString),
                        {}, {
                           success: function (data) {
                                let contact=data.split('|');
                                if (self.isEmptyS2S(data) && red === false) {
                                     console.log('GREEN');
                                     emailField.css('color', 'green');
                                     App.config.validEmail='';
                                } else {
                                     console.log('RED');
                                     console.log(data);
                                     console.log(contact[0]);
                                     console.log(contact[1]);
                                     emailField.css('color', 'red');
                                     red = true;
                                          errors['email'] = errors['email'] || {};
                                          errors['email'].required_validation = true;
                                     App.config.validEmail=[contact[0],contact[1]];
                                     app.alert.show('not_unique_email', {
                                        level: 'error',
                                        messages: app.lang.get('ERROR_POPUP_EMAILMUSTBEUNIQUE', 'Contacts', {name: contact[0]}),
                                        autoClose: false
                                    });
                                }
                            },
                           error: function (e) {
                                console.log('error');
                                console.log(e);
                           }
                      }, {async: true});
                }
            }
        })
    }
Parents
  • consider the following example. In this example we add a validation task that checks a certain account number field. In the success/error callbacks we execute the callback that we initialy received from the validation method. 

    // initialize method of the create/record.js

    this.model.addValidationTask('check_accountnumber',_.bind(this._doValidateAccountNumber,this));

    // the actual validation method:
    _doValidateAccountNumber: function(fields, errors, callback){
    console.log('validate account number');
            let acnumber = this.model.get('accountnumber_c');
            if(!_.isEmpty(acnumber) && !_.isUndefined(acnumber)){
                let options = {async: false};
                let url = app.api.buildURL('accounts','number/'+acnumber);
                app.api.call('read',url,options,{
                    success: _.bind(this.onValidAccountNumber,this,fields,errors,callback),
                    error: _.bind(this.onInvalidAccountNumber,this,fields,errors,callback)
                });
            }else{
                callback(null, fields, errors);
            }
        },


    onValidAccountNumber: function(fields,errors,callback){
            callback(null, fields, errors);
    },

    onInvalidAccountNumber: function(fields,errors,callback){
      errors['accountnumber_c'] = errors['accountnumber_c'] || {};
      errors['accountnumber_c'].account_number_duplicate_msg = true;
      callback(null, fields, errors);
    },
Reply
  • consider the following example. In this example we add a validation task that checks a certain account number field. In the success/error callbacks we execute the callback that we initialy received from the validation method. 

    // initialize method of the create/record.js

    this.model.addValidationTask('check_accountnumber',_.bind(this._doValidateAccountNumber,this));

    // the actual validation method:
    _doValidateAccountNumber: function(fields, errors, callback){
    console.log('validate account number');
            let acnumber = this.model.get('accountnumber_c');
            if(!_.isEmpty(acnumber) && !_.isUndefined(acnumber)){
                let options = {async: false};
                let url = app.api.buildURL('accounts','number/'+acnumber);
                app.api.call('read',url,options,{
                    success: _.bind(this.onValidAccountNumber,this,fields,errors,callback),
                    error: _.bind(this.onInvalidAccountNumber,this,fields,errors,callback)
                });
            }else{
                callback(null, fields, errors);
            }
        },


    onValidAccountNumber: function(fields,errors,callback){
            callback(null, fields, errors);
    },

    onInvalidAccountNumber: function(fields,errors,callback){
      errors['accountnumber_c'] = errors['accountnumber_c'] || {};
      errors['accountnumber_c'].account_number_duplicate_msg = true;
      callback(null, fields, errors);
    },
Children
No Data