field rendering twice

I have a custom field renderer on a datetime field with a snippet that looks like this:

var field = arguments[0],    value = skuid.utils.decodeHTML(arguments[1]),
   $ = skuid.$;
var model = skuid.$M('TempAdder');
if(value == null){
    value = skuid.time.getSFDate(new Date());
    value += 'T04:00:00';
    model.updateRow(model.getFirstRow(),'End\_Date\_\_c',value);
    console.log(value);
}
skuid.ui.fieldRenderers[field.metadata.displaytype][field.mode](field,value); 

I believe this was working fine before the new release but I might be wrong… Here is how my page looks now:

Any ideas?

If I comment out this line "model.updateRow(model.getFirstRow(),‘End_Date__c’,value);"everything works fine… can update row cause it to render twice?

Yes, that’s exactly what’s happening. We did make a change in Summer 14 that would cause this, and it is intentional. But it is easy to avoid.

There are various ways you can branch your logic so that the renderer is not run twice, but here is one of them:

var field = arguments[0],&nbsp; &nbsp; <br>&nbsp; &nbsp; value = skuid.utils.decodeHTML(arguments[1]),<br>&nbsp; &nbsp;$ = skuid.$;<br>var model = skuid.$M('TempAdder');<br>if (value == null) {<br>&nbsp; &nbsp; value = skuid.time.getSFDate(new Date());<br>&nbsp; &nbsp; value += 'T04:00:00';<br>&nbsp; &nbsp; model.updateRow(model.getFirstRow(),'End_Date__c',value);<br>&nbsp; &nbsp; console.log(value);<br>} else {<br>&nbsp; &nbsp;skuid.ui.fieldRenderers[field.metadata.displaytype][field.mode](field,value);<br>}

OK so just to understand this (because I use field renderers like crazy…) you guys added logic to automatically run the default renderer whenever any update to the model data happens?!

That’s close: what we did was to officially “register” all skuid.ui.Fields created for each Table and Field Editor field, so that any changes made via updateRow() would be reflected, immediately, in the UI, rather than you having to call save on the Model or list.render() .

This was done to eliminate the need for a lot of JavaScript code whose only purpose was to sync up the UI after Model data changes were made. Skuid now handles this natively.

This shouldn’t affect custom field renderers unless you are already doing things like finding all registered Lists and then calling list.render(), or if, like in this situation, you’re calling updateRow() within a custom field renderer — that is, if your Field Renderer has “side effects”. 

The biggest tool to be aware of when making Custom Field Renderers that will be helpful here is the initiatorId parameter that can be passed in to updateRow, and the field._GUID property. Another way to have rewritten the above code would be:

var field = arguments[0], &nbsp; &nbsp;<br>&nbsp; &nbsp; value = skuid.utils.decodeHTML(arguments[1]),<br>&nbsp; &nbsp;$ = skuid.$;<br>var model = skuid.$M('TempAdder');<br>if (value == null) {<br>&nbsp; &nbsp; value = skuid.time.getSFDate(new Date());<br>&nbsp; &nbsp; value += 'T04:00:00';<br>&nbsp; &nbsp; model.updateRow(model.getFirstRow(),'End_Date__c',value, <b>{ initiatorId: field._GUID }</b> );<br>}<br>skuid.ui.fieldRenderers[field.metadata.displaytype][field.mode](field,value);<br>

This works because when you pass in the initiatorId parameter to updateRow you’re letting Skuid know exactly which skuid.ui.Field is responsible for the update — that way, Skuid knows NOT to tell this Field about the update after it has been processed, because Skuid assumes you already know about it, because you’re the initiator, so of course you know about it, you caused it to happen! 

After Skuid Model changes happen, Skuid will call various API methods (see “Overriding and Extending Editors” in this tutorial), but it will only call them on Fields, Items, Lists, Editors that did NOT initiate the data changes.

OK sounds great I noticed that updateRow seemed to be working better thanks for the detailed explanation.