Thursday, November 23, 2017

Using ECMAScript 6 promises with JSOM

This is a small post for those of you that would be interested in using ECMAScript 6 promises with JSOM in SharePoint. A Promise represents the eventual completion (or failure) of an asynchronous operation, and its resulting value. Keep in mind that ECMAScript 6 might not be supported in all browsers. In that case, you could fall back to jQuery promises. If you want to use this in combination with EcexuteQueryAsync, you can. But you could also extend JSOM to provide a function that does this for you ...
You can use the following code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
// Extending JSOM
  SP.ClientContext.prototype.executeQuery = function (argument) {
    // Get a reference to this
    var that = this;
    // Create the promise
    var promise = new Promise(function (resolve, reject) {
      that.executeQueryAsync(
        function () { resolve(argument); }, 
        function (sender, e) { reject(e); }
      );
    });
    return promise;
  };

With that it is now easier to write something as follows:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
$(document).ready(function () {
    getUser().then(
      function (user, folder) {
        $('#message').text('Hello ' + user.get_title());
      },
      function (e) {
        alert('Failed to get user name. Error:' + e.get_message());
      }
    )
  });

  // This function prepares, loads, and then executes a SharePoint query to get the current users information
  function getUser() {
    var user = context.get_web().get_currentUser();
    context.load(user);
    return context.executeQuery(user);
  }

Tuesday, November 21, 2017

Mapping crawled properties on Site Collection level to Refinable* Managed Properties in SharePoint 2016

This blog post continues on one of my previous posts on the behavior on automatically created crawled and managed properties in SharePoint 2016. I got a question on how the PowerShell script in that blog post could help to map existing crawled properties to the Refinable* managed properties in a site collection (RefinableString00, RefinableString01, …).

First of all, to make things clear. You have to know that from SharePoint 2016 onwards, automatically generated crawled and managed properties are not stored inside the search schema database anymore. Instead, they are stored directly into the index. This is why, when using the PowerShell Cmdlets Get-SPEnterpriseSearchMetadataCrawledProperty and Get-SPEnterpriseSearchMetadataManagedProperty , you will not get any results, because those Cmdlets are looking inside the search schema, and not the index. Comparable to this, the New-* Cmdlets will also create them inside the search schema. On the other hand, the Refinable* managed properties are stored in the search schema, and configurable per site collection… (obvious, right? ;-))


Knowing these things, this implies that if you want to map a crawled property to a Refinable* managed property on site collection level, that you need to make sure the crawled property is created in the Search Schema before you map it to the existing managed property. The PowerShell I’ve used to demonstrate this is the following:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Add-PSSnapin Microsoft.SharePoint.PowerShell

# Get the Search Service Application
$ssa = Get-SPEnterpriseSearchServiceApplication -Identity "Search Service Application"

# Get Search category (origin was a site column)
$category = Get-SPEnterpriseSearchMetadataCategory -SearchApplication $ssa -Identity "SharePoint"

# Fulfillment Status
# Crawled property 1 (usable for refining): ows_Fulfillment_x0020_status
# Crawled property 2 (usable for structured search): ows_q_CHCS_Fulfillmentstatus

# Get the site
$site = Get-SPSite http://search.contoso.com

# Create crawled property
$crawledProperty = New-SPEnterpriseSearchMetadataCrawledProperty -SearchApplication $ssa -Category $category -VariantType 0 -PropSet "00130329-0000-0130-c000-000000131346" -Name "ows_Fulfillment_x0020_status" -IsNameEnum $false

# Find the existing managed property
$managedProperty = Get-SPEnterpriseSearchMetadataManagedProperty 'RefinableString00' -SearchApplication $ssa -SiteCollection $site.ID
$managedProperty.MappingsOverridden = $true;
$managedProperty.Update();

# Create the mapping
New-SPEnterpriseSearchMetadataMapping -SearchApplication $ssa -CrawledProperty $crawledProperty -ManagedProperty $managedProperty

Things to know about this is that I started from a site column with the name Fulfillment status and that this was a Choice. The site collection where I wanted to make the mapping was at http://search.contoso.com.

The crawled property is now correctly mapped, just make sure to start the crawler again, since you’ve made a change to the Search Schema.

clip_image002