Javascript throwing unsaved changes error when no changes have been made.

Matt SonesMatt Sones ๐Ÿ’Ž๐Ÿ’Ž๐Ÿ’Ž
edited March 2, 2017 in Questions
I'm getting an uncaught model (unsaved changes) when I run the following script more than once. I tried to implement a model check and save if there were changes, but to no avail. I still get hte uncaught changes error on the 'Open' model.

What am I missing?

Here's the code:
var mO = skuid.$M('Open'),ย  ย  model = skuid.$M('ApptInteractions'),
ย  ย  condition = model.getConditionByName('Date'),
ย  ย  curDate = condition.value;
var jsDate = (curDate == 'TODAY') ? new Date() : skuid.time.parseSFDate(curDate);
jsDate.setDate(jsDate.getDate()-1);
var prevDate = skuid.time.getSFDate(jsDate);
//Set Conditions
model.setCondition(condition, prevDate);
mO.setCondition(mO.getConditionByName('OpenDate'), prevDate);
//Requery models (if unsaved, save first)
if (!model.hasChanged) {
ย  ย  model.updateData();
} else {
ย  ย  model.save({
ย  ย  callback: function(results){
ย  ย  ย  ย  if(results.totalsuccess) {
ย  ย  ย  ย  ย  ย  model.updateData();
ย  ย  ย  ย  } else {
ย  ย  ย  ย  ย  ย  console.log('Appointments model save failed.');
ย  ย  ย  ย  }
ย  ย  }});
}
if (!mO.hasChanged) {
ย  ย  mO.updateData();
} else {
ย  ย  mO.save({
ย  ย  callback: function(results){
ย  ย  ย  ย  if(results.totalsuccess) {
ย  ย  ย  ย  ย  ย  mO.updateData();
ย  ย  ย  ย  } else {
ย  ย  ย  ย  ย  ย  console.log('Appointments model save failed.');
ย  ย  ย  ย  }
ย  ย  }});
}

//Refresh template
skuid.component.getById('DateTemplate').render();
Thanks!

Comments

  • Matt SonesMatt Sones ๐Ÿ’Ž๐Ÿ’Ž๐Ÿ’Ž
    edited February 10, 2017
    It looks like every time I activate and set the value of a condition on a model, and then try to query that model, it's throwing an "uncaught model 'Model' has unsaved changes." error.
  • edited March 2, 2017
    Under what circumstances does this script get run?
  • Matt SonesMatt Sones ๐Ÿ’Ž๐Ÿ’Ž๐Ÿ’Ž
    edited February 10, 2017
    I'm in the mobile page builder.ย User clicks a button (to display open appointments for the previous day).ย 

    I get the same error when the user clicks a different button and activates this action framework set:
    1. Activate and set value of model condition.
    2. Query Model
    3. Set Main Panel
    It throws the error before the query, even though I've made no changes to the model (as far as I can tell).
  • edited March 2, 2017
    What happens if you run a "Cancel Models" action / run model.cancel() and m0.cancel() in JavaScript before everything else?
  • Matt SonesMatt Sones ๐Ÿ’Ž๐Ÿ’Ž๐Ÿ’Ž
    edited February 10, 2017
    No dice.

    Fascinatingly, the error is getting triggered from the updateData() within the callback of the save() function:ย 
    image

    How could there be unsaved changes in the model? It was just saved!

  • edited March 2, 2017
    Better check to see what changes there are --- there must be something. Before the m0.updateData in the callback, do:

    console.log('Does m0 still have changes: ' + m0.hasChanged);
    console.log(m0.changes);
  • Matt SonesMatt Sones ๐Ÿ’Ž๐Ÿ’Ž๐Ÿ’Ž
    edited February 10, 2017
    slick. I didn't know model.changes was a thing.

    What am I looking at?
    image
  • edited March 2, 2017
    Looks like something is populating a value for the Name field on all of the rows in your Model, immediately after save --- do you have any After-Save Actions set up on a Deck in your page? Or any other JavaScript that might be bound to the save event on this Model?
  • Matt SonesMatt Sones ๐Ÿ’Ž๐Ÿ’Ž๐Ÿ’Ž
    edited March 2, 2017
    Zach,

    I searched through the XML, and couldn't find anything. I don't have any after-save actions on the panel in question.

    Mobile doesn't have any model actions, so that's out (also checked the XML just in case).

    The only thing I can think that might impact Name is a field renderer we have on Name on other panels... but the field isn't even rendered on the page, so I don't think that should make any difference?


  • edited December 21, 2016
    Aha! I bet that's it. Is there an updateRow() somewhere in the Field Renderer javascript?
  • edited December 21, 2016
    Matt, checked your renderer.fullName snippet, found this bit:
    value = CC_SCH.getFullNameFromField(field);
    skuid.ui.fieldRenderers[field.metadata.displaytype].read( field, value );
    // If our value is not equal to the current value of the "Name" field,
    // do an updateRow
    if (field.Name !== value) {
    model.updateRow(row,'Name',value,{ initiatorId: field._GUID });
    }
    I'm posting this to the Community for posterity to help others who run into a similar conundrum. One problem with the original was that field.Name was meaningless (i think you meant field.row.Name), but the bigger problem is that you are running the update check after the field renderer. Here's how I would do this:
    var combinedValue = CC_SCH.getFullNameFromField(field);
    // If our combined value is not equal to the current value of the field,
    // do an update, and change value appropriately
    if (combinedValue !== value) {
    ย  ย value = combinedValue;
    ย  ย model.updateRow(row,'Name',value,{ initiatorId: field._GUID });
    }
    skuid.ui.fieldRenderers[field.metadata.displaytype].read( field, value );
  • Matt SonesMatt Sones ๐Ÿ’Ž๐Ÿ’Ž๐Ÿ’Ž
    edited February 10, 2017
    Yep...
    /*** Name Renderer: ย registers Name Fields with the Model
    * and concatenates the names as they are being changed.
    **/
    var field = arguments[0],
    value = skuid.utils.decodeHTML(arguments[1]),
    model = field.model,
    row = field.row;
    //field.metadata.displaytype
    //register related fields.
    field.model.registerField(field, "First_Name__c");
    field.model.registerField(field, "Middle_Name__c");
    field.model.registerField(field, "Last_Name__c");
    value = CC_SCH.getFullNameFromField(field);
    skuid.ui.fieldRenderers[field.metadata.displaytype].read( field, value );
    // If our value is not equal to the current value of the "Name" field,
    // do an updateRow
    if (field.Name !== value) {
    model.updateRow(row,'Name',value,{ initiatorId: field._GUID });
    }
  • Matt SonesMatt Sones ๐Ÿ’Ž๐Ÿ’Ž๐Ÿ’Ž
    edited February 10, 2017
    Nice... thanks, Zach!


  • Matt SonesMatt Sones ๐Ÿ’Ž๐Ÿ’Ž๐Ÿ’Ž
    edited February 10, 2017
    Zach... I'm still getting the error after updating the renderer as you indicated.

    It's still changing the value of Name after every save, apparently.

    What's the best way around this?

  • edited March 2, 2017
    Matt, ideally what I would do is to remove the Field Renderer altogether --- and use Model Actions. I would setup a single Model action on your "Open" Model listening for changes on the First Name, Middle Name, or Last Name fields, whose action is to combine those together into the desired concatenated Name format, and put this value into the Name field on the row in question. However, Model Actions are only available via XML in the Mobile Composer --- they work fine, but you have to define them in XML. I could suggest how to do this if you are open to it, or we could continue to debug your renderer code.
  • Matt SonesMatt Sones ๐Ÿ’Ž๐Ÿ’Ž๐Ÿ’Ž
    edited February 10, 2017
    Smart. I'll work on that now. We have a desktop version of the page as well, so I'll create the model actions there and paste them into the mobile XML.
  • Matt SonesMatt Sones ๐Ÿ’Ž๐Ÿ’Ž๐Ÿ’Ž
    edited February 10, 2017
    Zach (et al.),

    i'm using model actions to set Name to the correct value, instead of a custom renderer. However, I'm struggling to get the field to render again when the field is updated.

    skuid.ui.Field('Name').render() ?

    Will that render every field on every model called Name?
  • edited March 2, 2017
    All affected Name fields should automatically re-render if you update the value of that field on any rows in the Model. Did you remove the custom field renderer snippet from all of the Name fields?
  • Matt SonesMatt Sones ๐Ÿ’Ž๐Ÿ’Ž๐Ÿ’Ž
    edited February 10, 2017
    There are no custom renderers on Name.ย 

    This is the model action set for when First Name, Middle Name, or Last Name are updated:
    image

    However, this is the result after typing in those three fields:
    image

    Help?

  • Matt SonesMatt Sones ๐Ÿ’Ž๐Ÿ’Ž๐Ÿ’Ž
    edited February 10, 2017
    If I set render conditions on the Name (Full Name) field so that it will only render when First_Name__c is != null, then I get Name = First.

    But it does not rerender when typing middle or last.
  • edited March 2, 2017
    Is the Name field an Autonumber in Salesforce / is it editable? I don't think that the update will appear unless the field is editable.

    Also, try using triple-braces instead of double. (e.g. {{{FirstName}}} instead of {{FirstName}} )ย 
  • Matt SonesMatt Sones ๐Ÿ’Ž๐Ÿ’Ž๐Ÿ’Ž
    edited February 10, 2017
    Ah.. that was it. Apparently it was set as an Autonumber instead of Text. Thanks!
Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!