Sometimes I feel bad for junior front-end developers who think they have a decent handle on things, and then get thrown into the world of SharePoint. They don’t have the SharePoint Spidey-sense that tells them something simple is going to go horribly wrong.

I was called on to assist a junior developer who was tearing his hair out trying to do simple CRUD operations on list items in SharePoint in an Angular application. I’d already written a (somewhat) simplifying Angular service to deal with most of the annoying parts of the REST API, so I was baffled that he was having so much trouble with it.

So I stepped into the code with him, making sure he was calling my service correctly. He was. I began to panic. Was there a bug in my service? I stepped into the service code. Everything looked fine, and SharePoint returned the proper “201 CREATED” response. But every field except one was being set.

The name of that field was “DisplayName”.

Curious.

I proceeded to create a new Custom List called “TestThisBug.” I created a field called “DisplayName” and another field called “FooDisplayName.”

sp2013-displayname-bug-in-interface

Simple, right? Then I tried to get the fields via the REST API.

sp2013-displayname-bug-in-rest

The field did not appear. Curiouser and curiouser.

I tweeted the tweet above, and told the developer to name the field something else and be on his way. I wondered, “What if we try the same operations using the JSOM?”

So, on my SharePoint 2013 VM, I fired up a Site Collection, created my list, and wrote me some JSOM code. I wrote some code that will get that list item, select a few fields (including “DisplayName”) and just display it in a table.

sp2013-every-field-but-displayname

I got every field I asked for, except for “DisplayName” which was silently disregarded. When I tried to ask for it directly via get_item('DisplayName') I was told it wasn’t initialized, despite the fact that I’d explicitly requested it.

sp2013-uninitialized-property-jsom

I began to wonder if I would run into the same creation issue my coworker was encountering. I wrote some more JSOM code to actually create a list item with the “DisplayName” field set. And, even more strangely… It worked!

sp2013-succesfully-created-item-with-jsom

I then logged on to my Office 365 Dev Tenant to see if this is still an issue.

o365-displayname-bug-in-rest

o365-displayname-bug-with-jsom-added-item

Yup! Sure is! You can see here that I can get the field name from the list via list.get_fields(), but when I return list items, the field is not returned, despite explicitly requesting it. You can also see that the “DisplayName” field that is returned from get_fields() doesn’t have any super-secret internal name that I’m missing.

But, as before, adding a list item with that field via JSOM works just fine:

o365-displayname-bug-with-jsom-added-item

So, kids, I guess the moral of this story is pretty simple: Don’t name your fields “DisplayName.”

Here’s the bug-test JSOM code.

<script src="https://code.jquery.com/jquery-3.1.0.min.js" integrity="sha256-cCueBR6CsyA4/9szpPfrX3s49M9vUU5BgtiJj06wt/s=" crossorigin="anonymous"></script>
<script type="text/javascript" src="/_layouts/15/sp.runtime.js"></script>
<script type="text/javascript" src="/_layouts/15/sp.js"></script>
<script type="text/javascript">
var listItemCollection;
var listFields;
$(document).ready(function () {
var clientContext = new SP.ClientContext(_spPageContextInfo.webAbsoluteUrl);
var oList = clientContext.get_web().get_lists().getByTitle('TestThisBug');
var query = SP.CamlQuery.createAllItemsQuery();
listItemCollection = oList.getItems(query);
listFields = oList.get_fields();
clientContext.load(listItemCollection, 'Include(Title, DisplayName, FooDisplayName, Created, Modified, GUID)');
clientContext.load(listFields);
clientContext.executeQueryAsync(onQuerySucceeded, onQueryFailed);
function onQuerySucceeded() {
var fieldEnumerator = listFields.getEnumerator();
while (fieldEnumerator.moveNext()) {
var field = fieldEnumerator.get_current();
$('#jsomFields').append('<li>' + field.get_title() + '(' + field.get_internalName() + ') </li>');
}
var listItemEnumerator = listItemCollection.getEnumerator();
var listItem;
var gotFieldNames = false;
while (listItemEnumerator.moveNext()) {
listItem = listItemEnumerator.get_current();
var myFieldValues = listItem.get_fieldValues();
if (!gotFieldNames) {
var fields = Object.keys(myFieldValues);
for (var i = 0; i < fields.length; i++) {
$('#fieldNames').append('<td>' + fields[i] + '</td>')
}
gotFieldNames = true;
}
var tableRow = $('#fieldValues').append('<tr></tr>');
for (var j = 0; j < fields.length; j++) {
tableRow.append('<td>' + myFieldValues[fields[j]] + '</td>');
}
}
}
function onQueryFailed(sender, args) {
$('#errorArea').text('Error: ' + args.get_message());
}
var newListItem;
$('#addItemButton').click(function () {
var createItemInfo = new SP.ListItemCreationInformation();
newListItem = oList.addItem(createItemInfo);
newListItem.set_item('Title', 'A JSOM Created Item');
newListItem.set_item('FooDisplayName', 'A JSOM Created Foo Display Name');
newListItem.set_item('DisplayName', 'A JSOM Created Display Name');
newListItem.update();
clientContext.executeQueryAsync(onAddItemSucceeded, onQueryFailed);
});
function onAddItemSucceeded() {
$('#successArea').text('Successfully added item via JSOM');
}
});
</script>
<button type="button" id="addItemButton">Add an Item</button>
<h1>Field Values</h1>
<table border="1">
<thead>
<tr id="fieldNames">
</tr>
</thead>
<tbody id="fieldValues">
</tbody>
</table>
<h1>All Fields from JSOM</h1>
<ul id="jsomFields"></ul>
<div id="successArea"></div>
<div id="errorArea"></div>
view raw bugTest.html hosted with ❤ by GitHub