title: JSOM/Javascript get content type name with all other columns
body: <p>I have the following method which correctly gets list items from a sharepoint query, however the content type needs a special treatment and its not returned.</p>
  
  <pre><code>function getListItems(listId, camlQueryString, selectProperties){  
                          var deferred = $q.defer();
                          var context = SP.ClientContext.get_current();
                          var web = context.get_web();
  
                          var list = web.get_lists().getById(listId);
  
                          var camlQuery = new SP.CamlQuery();
                              camlQuery.set_viewXml(camlQueryString);
  
                          var listItems = list.getItems(camlQuery);
  
                          //var includesString = "Include(ID,Title,AssignedTo, WorkflowOutcome, ApproverComments, FileRef, WorkflowItemId, Created, Modified)"; // + selectProperties.join(", ") +  ")";
                          if(selectProperties) {
                              var includesString = convertSelectPropertiesToIncludesString(selectProperties);
                              context.load(listItems, includesString);
                          } else {
                              context.load(listItems);
                          }
                          context.executeQueryAsync(
                             function() {
                                  $log.info("Successfully retrieved list item result");
  
                                  deferred.resolve(listItems);
                             },
                             function(error, errorInfo) {
                                  $log.warn("Retrieving list item result failed");
  
                                  deferred.reject(errorInfo);
                             }
                          );
                          return deferred.promise;
                      }
  </code></pre>
  
  <p>I need the content type name to be returned in the same array of listitems as another field.</p>
  
  <p>I have found a few examples, but I am not sure how to integrate that code into mine because it seems a double call is needed for eachitem.</p>
  
  <p><strong>Update 1</strong></p>
  
  <p>I  try to use the above method from this:</p>
  
  <pre><code>function GetRelatedBillingDocumentsFromList(selectProperties, currentBillCyclePath, clientCode, jobCodes, engagementCode, enhanceFunctions) {
                  $log.info("Retrieving related billing documents for bill cycle with name [" + currentBillCyclePath + "]");                  
                  var deferred = $q.defer();
                  var webUrl = _spPageContextInfo.webAbsoluteUrl;
                  var viewFields = spService.ConvertSelectPropertiesToViewFields(selectProperties);
                  // query must return the documents for the same client but in other bill cycles not the current one
                  var camlQuery = '&lt;View&gt;' +   viewFields + 
                          '&lt;Query&gt;' +
                              '&lt;Where&gt;' +
                                  //'&lt;And&gt;' +
                                      '&lt;Eq&gt;' +
                                          '&lt;FieldRef Name="ClientCode" /&gt;' +
                                          '&lt;Value Type="Text"&gt;'+ clientCode + '&lt;/Value&gt;' +
                                      '&lt;/Eq&gt;' +
                                  //  '&lt;Neq&gt;' +
                                  //      '&lt;FieldRef Name="ContentType" /&gt;' +
                                  //      '&lt;Value Type="Computed"&gt;Bill Cycle&lt;/Value&gt;' +
                                  //  '&lt;/Neq&gt;' +
                                  //'&lt;/And&gt;' +
                              '&lt;/Where&gt;' +
                              //'&lt;QueryOptions&gt;' +
                              //  '&lt;ViewAttributes Scope="RecursiveAll" /&gt;' +
                              //'&lt;/QueryOptions&gt;' +
                          '&lt;/Query&gt;' +
                      '&lt;/View&gt;';
  
                  var billCyclesListId = "{c23bbae4-34f7-494c-8f67-acece3ba60da}";                    
                  spService.GetListItems(billCyclesListId, camlQuery, selectProperties)
                  .then(function(listItems) {
                      var listItemsWithValues = [];
                      if(listItems) {
                          var enumerator = listItems.getEnumerator();
                          while (enumerator.moveNext()) {
                              var listItem = enumerator.get_current();
                              var listItemValues = [];                                
                              selectProperties
                              .forEach(function(propertyName) {
                                  if(propertyName==='ContentType'){
                                      var value = listItem.get_item('ows_ContentType');
                                  }else{
                                      var value = listItem.get_item(propertyName);
                                  }                               
                                  listItemValues[propertyName] = value;
                              });
  
                              listItemsWithValues.push(listItemValues);
                          }
                      }
  
                      // Create the full item url
                      listItemsWithValues.forEach(function(listItem) {
                          var fileDirRef = listItem["FileRef"];
                          var id = listItem["ID"];
                          var serverUrl = _spPageContextInfo.webAbsoluteUrl.replace(_spPageContextInfo.webServerRelativeUrl,"");                          
                          var dispFormUrl = serverUrl + fileDirRef + "/DispForm.aspx?ID=" + id;
                          listItem["FileRef"] = dispFormUrl;
                      });
  
                      var enhancedListItemValues = spService.SpSearchQuery.EnhanceSearchResults(listItemsWithValues, enhanceFunctions);                       
                      deferred.resolve(listItemsWithValues);
                  })
                  .catch (function (message) {
                      deferred.reject();
                  });
  
                  return deferred.promise;
              }
  </code></pre>
  
  <p>as you can see I need a way to return content type name in the same array of values in a simple way</p>